杭电 6319

题目链接: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;
}
原文地址:https://www.cnblogs.com/Accepting/p/11807256.html