Problem A. Ascending Rating
Before the start of contest, there are nn ICPC contestants waiting in a long queue. They are labeled by 11 to nn from left to right. It can be easily found that the ii-th contestant's QodeForces rating is aiai.
Little Q, the coach of Quailty Normal University, is bored to just watch them waiting in the queue. He starts to compare the rating of the contestants. He will pick a continous interval with length mm, say [l,l+m−1][l,l+m−1], and then inspect each contestant from left to right. Initially, he will write down two numbers maxrating=−1maxrating=−1 and count=0count=0. Everytime he meets a contestant kk with strictly higher rating than maxratingmaxrating, he will change maxratingmaxrating to akak and countcount to count+1count+1.
Little T is also a coach waiting for the contest. He knows Little Q is not good at counting, so he is wondering what are the correct final value of maxratingmaxrating and countcount. Please write a program to figure out the answer.
Input
The first line of the input contains an integer T(1≤T≤2000)T(1≤T≤2000), denoting the number of test cases.
In each test case, there are 77 integers n,m,k,p,q,r,MOD(1≤m,k≤n≤107,5≤p,q,r,MOD≤109)n,m,k,p,q,r,MOD(1≤m,k≤n≤107,5≤p,q,r,MOD≤109) in the first line, denoting the number of contestants, the length of interval, and the parameters k,p,q,r,MODk,p,q,r,MOD.
In the next line, there are kk integers a1,a2,...,ak(0≤ai≤109)a1,a2,...,ak(0≤ai≤109), denoting the rating of the first kk contestants.
To reduce the large input, we will use the following generator. The numbers p,q,rp,q,rand MODMOD are given initially. The values ai(k<i≤n)ai(k<i≤n) are then produced as follows :
ai=(p×ai−1+q×i+r)modMODai=(p×ai−1+q×i+r)modMOD
It is guaranteed that ∑n≤7×107∑n≤7×107 and ∑k≤2×106∑k≤2×106.
Output
Since the output file may be very large, let's denote maxratingimaxratingi and counticounti as the result of interval [i,i+m−1][i,i+m−1].
For each test case, you need to print a single line containing two integers AA and BB, where :
AB==∑i=1n−m+1(maxratingi⊕i)∑i=1n−m+1(counti⊕i)A=∑i=1n−m+1(maxratingi⊕i)B=∑i=1n−m+1(counti⊕i)
Note that ``⊕⊕'' denotes binary XOR operation.
Sample Input
1 10 6 10 5 5 5 5 3 2 2 1 5 7 6 8 2 9
Sample Output
46 11
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6319
题目大意:在长度为n的数组中,对于每个长度为 m 的连续子区间,求出子区间 的最大值以及从左往右扫描该区间时区间最大值的更新次数。
输入描述:n m k p q r mod ,给出长度为k的数组,[ k+1,n ]区间的部分 按照公式: a[i]=(a[i-1]*p+q*i+r)%mod 计算
思路:单调队列,维护长度为m的滑动窗口的最大值,还要维护更新的次数,从后往前遍历,维护队列的单调性,此时队列的长度就是更新的次数
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int N=10000005;
ll a[N];
int qu[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll n,m,k,p,q,r,mod;
scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mod);
for(int i=1;i<=k;i++)
scanf("%lld",&a[i]);
for(int i=k+1;i<=n;i++)
a[i]=((a[i-1]*p)%mod+(q*i)%mod+r)%mod;
ll head=1,tail=0;
ll ans1=0,ans2=0;
for(ll i=n;i>=n-m+1;i--)
{
while(a[i]>=a[qu[tail]]&&head<=tail) --tail;
qu[++tail]=i;
if(i==n-m+1)
{
ans1+=a[qu[head]]^i;
ans2+=(tail-head+1)^i;
}
}
for(ll i=n-m;i>=1;i--)
{
while(qu[head]-i+1>m&&head<=tail)
{
head++;
}
while(a[i]>=a[qu[tail]]&&head<=tail) --tail;
qu[++tail]=i;
//printf("%d %lld %lld\n",i,a[qu[head]],(ll)tail-head+1);
ans1+=a[qu[head]]^i;
ans2+=(tail-head+1)^i;
}
printf("%lld %lld\n",ans1,ans2);
}
return 0;
}