HDU 6319&&18多校3A Ascending Rating 【單調佇列】
阿新 • • 發佈:2019-02-20
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 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 m, say [l 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 m 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);
}
}