版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36651153/article/details/82354079
反着跑一个单调队列
代码如下
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int t,a[10000007],n,m,k,p,q,r,mod;
int deq[10000007];
int main()
{
scanf("%d",&t);
while(t--) {
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+r)%mod;
}
int s=0,t=0;
long long sa=0,sb=0;
for(int i=n;i>=1;i--) {
while(s<t&&a[deq[t-1]]<=a[i]) t--;
deq[t++]=i;
if(i<=n-m+1){
sa+=(i^a[deq[s]]);
sb+=(i^(t-s));
if(deq[s]==i+m-1) {
s++;
}
}
}
printf("%lld %lld\n",sa,sb);
}
}