2018 Multi-University Training Contest 3 hdu多校第三场 Problem A:Ascending Rating(单调队列)

题目大意:

给你n个数,对于第i个数求区间(i , i+m-1)的最大值以及严格递增序列的长度。

解题思路:

n是1e7,所以肯定是单调队列,但是单调队列注意要倒着维护,倒着维护感觉会比较的简单。最大值直接取 head 即可,长度即tail-head的长度。

Ac代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e7+5;
int n,m,k,p,q,r,mod,a[maxn],que[maxn];
int main()
{
    int QAQ;
    scanf("%d",&QAQ);
    while(QAQ--)
    {
        scanf("%d%d%d%d%d%d%d",&n,&m,&k,&p,&q,&r,&mod);
        for(int i=1;i<=n;i++)   //处理出n个数
        {
            if(i<=k) scanf("%d",&a[i]);
            else a[i]=(1LL*p*a[i-1]+1LL*q*i+1LL*r)%mod;
        }
        ll A=0,B=0,mx,cou;
        int head=0,tail=0;
        for(int i=n;i>=1;i--)   //单调队列
        {
            while(tail>head&&a[que[tail-1]]<=a[i]) tail--;  //当尾结点加入时只能比上个结点小
            que[tail++]=i;
            while((que[head]>i+m-1)&&head<tail) head++; //判断头节点是否合法
            if(i<=n-m+1)
            {
                mx=a[que[head]],cou=tail-head;  //统计最大值以及长度 计算答案
                A+=(1LL*mx)^(1LL*i);
                B+=(1LL*cou)^(1LL*i);
            }
        }
        printf("%lld %lld\n",A,B);
    }
}

猜你喜欢

转载自blog.csdn.net/f2935552941/article/details/81291971