题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6319
题解:https://blog.csdn.net/Sirius_han/article/details/81318266
思路:倒着维护一个单调数组,数组内元素的个数就是count值,尾部就是maxrating。由于题目要求的是单调递增,倒着维护应该是单调递减,当前值大于等于数组头部的值,则需要出栈。
维护的区间长度为m,如果区间长度大于m,从尾部删除元素。
AC代码:
#include<bits/stdc++.h> using namespace std; const int N=1E7+7; typedef long long ll; ll arr[N]; ll mark[N]; ll n,m,k,p,q,r,mod; void solve(){ scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mod); for(ll i=1;i<=k;i++) scanf("%lld",&arr[i]); for(ll i=k+1;i<=n;i++) arr[i]=(p*arr[i-1]+q*i+r)%mod; ll l=r=1; ll a=0,b=0; for(ll i=n;i>0;i--){ while(r>l&&arr[i]>=arr[mark[r]]) r--; mark[++r]=i; while(mark[l+1]-mark[r]+1>m) l++; if(i<=n-m+1){ a+=arr[mark[l+1]]^i; b+=(r-l)^i; } } printf("%lld %lld ",a,b); } int main(){ int t ; scanf("%d",&t); while(t--) solve(); return 0; }