Problem A. Ascending RatingTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3287 Accepted Submission(s): 1083 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. 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个为一段,一共(n-m+1)段,1:求出每一段最大值与 i (就是第几段)异或的和
2:求出每个区间最大值替换的次数与 i 的异或的和。
单调队列维护最大值,队列的长度就是count
#include<map>
#include<stack>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define maxn 10000005
#define inf 0x3f3f3f
#define ll long long
#define mod 7
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
ll a[maxn];
ll s[maxn];
int main(){
int t;
scanf("%d",&t);
while(t--){
ll m,n,k,p,q,r,md;
scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&md);
for(int i=1;i<=n;i++){
if(i<=k)scanf("%lld",&a[i]);
else
a[i]=((p*a[i-1])%md+(q*i)%md+r)%md;
}
int head=0,near=-1;
ll x=0,y=0;
for(int i=n;i>n-m+1;i--){
while(head<=near&&a[s[near]]<=a[i])near--;
s[++near]=i;//队列里存的是下标
}
for(int i=(n-m+1);i>=1;i--){
while(head<=near&&a[s[near]]<=a[i])near--;
s[++near]=i;
while(s[head]-i>=m)head++;//保证队列里存的都是在当前i这个区间里。
x+=(i^a[s[head]]);y+=(i^(near-head+1));
}
printf("%lld %lld\n",x,y);
}
}