题目大意:
给定n m k,p q r mod,
给出序列的前k项 之后的按公式 a[i]=(p×a[i-1]+q×i+r)%mod 递推
求序列中每个长度为m的连续区间的
该区间最大值与第一位的位置异或 的总和
该区间的最长上升子序列长度与第一位的位置异或 的总和
区间最大值。。可参考另篇单调队列题解滑动最小值
从后向前维护单调队列的话
对于第i个位置为第一位的对应区间来说
单调队列中的最大值为区间最大值
单调队列的长度就是从区间最大值到a[i]的最长下降子序列长度
(反过来即从a[i]到区间最大值的最长上升子序列长度)

#include <bits/stdc++.h> #define LL long long using namespace std; const int N=1e7+5; int n,m,k,p,q,r,mod,a[N],que[N]; int main() { int t; 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<=n;i++) { if(i>k) a[i]=(((LL)p*a[i-1])%mod+(LL)q*i%mod+(LL)r)%mod; else scanf("%d",&a[i]); } LL MAX=0, CNT=0; int L=0, R=0; for(int i=n;i>0;i--) { while(L<R && a[que[R-1]]<=a[i]) R--; que[R++]=i; if(i+m-1<=n) { while(que[L]>i+m-1 && L<R) L++; MAX+=(i^a[que[L]]); CNT+=(i^(R-L)); } } printf("%lld %lld ",MAX,CNT); } return 0; }