题意略。
思路:倒着使用单调队列,大的放在前,小的放在后。
详见代码:
#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL maxn = 1e7 + 5; LL a[maxn]; int n,m,k; LL p,q,r,mod; int que[maxn],head,tail; LL ans[maxn]; LL generator(int i){ return ((p * a[i - 1]) % mod + q * i % mod + r) % mod; } int main(){ int T; scanf("%d",&T); while(T--){ head = tail = 0; scanf("%d%d%d%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mod); for(int i = 1;i <= k;++i) scanf("%lld",&a[i]); for(int i = k + 1;i <= n;++i) a[i] = generator(i); for(int i = n;i >= n - m + 1;--i){ while(head < tail && a[que[tail - 1]] <= a[i]) --tail; que[tail++] = i; } LL A = 0,B = 0; A += a[que[head]] ^ (n - m + 1); B += (tail - head) ^ (n - m + 1); //printf("%d ",tail - head); for(int i = n - m;i >= 1;--i){ while(que[head] > i + m - 1 && head < tail) ++head; while(head < tail && a[que[tail - 1]] <= a[i]) --tail; que[tail++] = i; A += a[que[head]] ^ i; B += (tail - head) ^ i; // printf("%d ",tail - head); } printf("%lld %lld ",A,B); } return 0; }