-
Problem A. Ascending Rating
- HDU - 6319
- 给定一个序列 a[1..n],对于每个长度为 m 的连续子区间, 求出区间 a 的最大值。
- 以及从左往右扫描该区间时 a 的最大值的 变化次数。 1 ≤ m ≤ n ≤ 1e7
- 逆向进行单调队列维护最大值,(i—i+m-1)序列内的最大值,此时合法区间单调队列中元素的个数就是最值改变次数。
-
#include<bits/stdc++.h> using namespace std; #define maxn 11234111 #define ll long long int n,m,k,q,p,r,mod,t; int que[maxn],head,tail; ll a[maxn],A,B; int main() { scanf("%d",&t); while(t--) { A=B=head=0; tail=-1; 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) scanf("%lld",&a[i]); else a[i]=((ll)p*a[i-1]+(ll)q*i+r)%mod; } for(int i=n; i>=1; i--) { while(tail>=head&&a[que[tail]]<=a[i])tail--; que[++tail]=i; while(tail>=head&&que[head]-i>m-1)head++; if(tail>=head&&i<=n-m+1) { A+=(a[que[head]]^i); B+=((tail-head+1)^i); } } printf("%lld %lld\n",A,B); } return 0; }