Problem A. Ascending Rating
题意: 给一个序列,求长为m的n-m+1个区间的最大值和最大值更新次数
思路: 单调队列维护长为m的区间最大值没问题... 至于后面的最大值更新次数,把序列倒过来,再从前往后扫,对应的队列中的size,就是长为m的区间中,从第一个数开始单调上升序列的长度了
单调队列除了能维护区间最大值之外,还能维护从第i个作为起点,到第i+m-1区间的 最大值更迭次数
#include<cstdio>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e7+7;
//const int MOD=1e9+7;
template <class T>
bool sf(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
int n,m,p,q,k,r,mod;
int a[N];
void mian(){
sf(n),sf(m),sf(k);sf(p);
sf(q),sf(r),sf(mod);
for(int i=1;i<=k;i++) sf(a[i]);
for(int i=k+1;i<=n;i++) a[i]=(1ll*p*a[i-1]+1ll*q*i+r)%mod;
deque<pair<int,int> > q;
reverse(a+1,a+1+n);
// for(int i=1;i<=n;i++) cout << a[i]<<" ";
// cout << endl;
ll A=0,B=0;
int jj=n-m+1;
for(int i=1,j=1;i<=n-m+1;i++){
while(j<=i+m-1){
while(!q.empty() && a[j]>=q.back().F) q.pop_back();
q.push_back({a[j],j++});
}
while(q.front().S< i) q.pop_front();
A=A+(q.front().F ^ jj);
if(q.front().F!=0) B=B+((int)q.size() ^ jj);
// cout << q.front().F<< "^" <<jj<<endl;
// cout << q.size()<< "^" <<jj<<endl;
// cout <<"-----------"<<endl;
jj--;
}
printf("%lld %lld\n",A,B);
}
int main(void){
int T;
sf(T);
while(T--){
mian();
}
return 0;
}