| ||||
Problem A. Ascending RatingTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3898 Accepted Submission(s): 1285 Problem Description Before the start of contest, there are n ICPC contestants waiting in a long queue. They are labeled by 1 to n from left to right. It can be easily found that the i-th contestant's QodeForces rating is ai.
Input The first line of the input contains an integer T(1≤T≤2000), denoting the number of test cases.In each test case, there are 7 integers 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,MOD. In the next line, there are k integers a1,a2,...,ak(0≤ai≤109), denoting the rating of the first k contestants. To reduce the large input, we will use the following generator. The numbers p,q,r and MOD are given initially. The values ai(k<i≤n) are then produced as follows : ai=(p×ai−1+q×i+r)modMOD It is guaranteed that ∑n≤7×107 and ∑k≤2×106.
Output Since the output file may be very large, let's denote maxratingi and counti as the result of interval [i,i+m−1].For each test case, you need to print a single line containing two integers A and B, where : AB==∑i=1n−m+1(maxratingi⊕i)∑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
| ||||
题意:给定一个长度为n的序列。现在问你每个区间长度为m的子序列最大值异或上i和最大值变化次数异或上i的求和。
分析:反向求一个单调递减队列。单调队列:以单调递减为例,维护一个队列,每次踢出不在此区间的数,然后加入a[i],大于等于a[i]的数都要提前踢出。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e7+10;
int a[N],que[N];
int n,m,k,q,p,r,MOD,n2;
int main()
{
int TA,l,r;
scanf("%d",&TA);
while(TA--)
{
LL ans1=0,ans2=0;
scanf("%d%d%d%d%d%d%d",&n,&m,&k,&p,&q,&r,&MOD);
for(int i=1;i<=k;i++)scanf("%d",&a[i]);
for(int i=k+1;i<=n;i++)a[i]=(1ll*p*a[i-1]+1ll*q*i+1ll*r)%MOD;
n2=n/2;
for(int i=1;i<=n2;i++)swap(a[i],a[n-i+1]);
l=0,r=0;que[0]=0;
for(int i=1;i<=n;i++)
{
while(i-que[l]>=m&&l<=r)l++;
while(r>=l&&a[que[r]]<=a[i])r--;
r++;
que[r]=i;
if(i>=m)
{
ans1+=(1ll*n-i+1)^(1ll*a[que[l]]);
ans2+=(1ll*n-i+1)^(1ll*(r-l+1));
}
}
printf("%lld %lld\n",ans1,ans2);
}
}