給出一個數列長度爲n 求從左往右的每個長度爲m的子區間的最大值maxnum,以及每個子區間從左往右數最大值變化的次數count、
maxnum好求,單調隊列維護一下就行了, count想了很久都有bug,看了題解是從又往左進行單調隊列這樣單調隊列裏就會依次保存這個區間內的最大數,次大數,第三大數。。。,隊列的size就是count值
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int mx = 1e7+5;
const int INF = 0x3f3f3f3f;
int n, m, k, p, q, r, mod;
int num[mx];
int Q[mx], rear, front;
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 <= k; i++)
scanf("%d", &num[i]);
for (int i = k+1; i <= n; i++)
num[i] = (1LL*p*num[i-1] + 1LL*q*i + r) % mod;
front = rear = 0;
int maxrt = -1, count = 0;
long long A = 0, B = 0;
for (int i = n; i >= 1; i--)
{
while (rear > front && num[Q[rear-1]] <= num[i]) rear--;
Q[rear++] = i;
while (rear > front && Q[front] - i + 1 > m) front++;
if (i <= n-m+1)
{
A += (long long)num[Q[front]] ^ i;
B += (long long)(rear-front) ^ i;
//printf("i = %d maxrt = %d count = %d\n",i-m+1, num[Q[front]], rear-front+1);
}
}
printf("%lld %lld\n",A, B);
}
return 0;
}