Title Meaning
There is a sequence of length n. now we give the first k numbers of your sequence and a recurrence formula to let you calculate all the values of the sequence. Then divide a continuous interval with length of m and ask the sum value of the maximum value exclusive or i in all the intervals you have drawn, and the sum value of the maximum value change times exclusive or i in the interval.
Solving problems
The key of this problem is to find the maximum value of a sequence and the number of changes of the maximum value. We will think of using monotone queue to maintain. We will reverse the sequence to maintain a decreasing monotone queue, so that the element of the queue head is the maximum value, and the number of elements in the queue is the number of changes of the maximum value.
If we maintain a monotone queue in reverse, it means that the elements in the queue are decreasing. Then every time we insert a value, we will compare it with the end of the queue. If it is larger than the end of the queue, we will remove the end of the queue. In this way, the number of elements in the queue is the maximum number of changes.
Code part
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=2e7+10;
int n,m,k,p,q,r,mod;
int a[maxn],maxval[maxn],cunt[maxn],que[maxn];///The que array stores the subscripts of the a array
ll ans,sum;
void getmax()
{
int head=0,tail=0;
for(int i=n; i>=1; i--)
{
while(head<tail&&a[que[tail-1]]<=a[i])///Pop up the end of team value when a[i] is larger than the end of team value
tail--;
que[tail++]=i;///Insert a[i], insert subscript instead of value, easy to pop up from the team head
if(i>n-m+1)
continue;
while(que[head]>i+m-1)///Pop up numbers not in interval maintenance
head++;
//printf("%d %d %d %d %d\n",i,tail,head,tail-head,a[que[head]]);
maxval[i]=a[que[head]];
cunt[i]=tail-head;
}
}
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",&a[i]);
}
for(int i=k+1; i<=n; i++)
{
a[i]=((ll)p*a[i-1]%mod+(ll)q*i%mod+r%mod)%mod;
}
sum=0,ans=0;
getmax();
for(int i=1; i<=n-m+1; i++)
{
ans+=maxval[i]^i;
sum+=cunt[i]^i;
}
printf("%lld %lld\n",ans,sum);
}
return 0;
}