Ascending Rating

本文介绍了一种使用单调队列优化算法求解区间最大值的方法,并通过实例代码详细解释了其实现过程。该算法能够在O(n)的时间复杂度内完成计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

链接: 题目链接

思路:

    用单调队列来进行优化,在此复习一下什么是单调队列,单调队列里面存放的是一段区间里面按某种关系排列的单调序列,下面就以单调递减为例进行说明,在往单调队列里面添加元素的时候,如果队列的队尾比添加的元素要小得话,那就把队尾元素弹出,一直到队列为空或者队尾元素大于要添加的元素,再将要添加的元素添加进这个单调队列,原则就是,越晚添加的元素越有用,这样可以在O(n)的时间内求出区间的最大值。

代码:

#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;

const int maxn=1e7+5;
LL n,m,k,p,q,r,MOD;

LL num[maxn]={0};
LL imax[maxn]={0};
LL times[maxn]={0};
LL que[maxn]={0};

void slove()
{
    int head,tail;
    head=tail=0;
    for(int i=n;i>0;i--)
    {
        while(head<tail&&num[que[tail-1]]<=num[i])
            tail--;
        que[tail++]=i;
        if(i>n-m+1)
            continue;
        while(que[head]>i+m-1)
            head++;
        imax[i]=num[que[head]];
        times[i]=tail-head;
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&MOD);
        for(int i=1;i<=k;i++)
            scanf("%lld",&num[i]);
        for(int i=k+1;i<=n;i++)
            num[i]=(p*num[i-1]+q*i+r)%MOD;
        slove();
        LL sum1,sum2;
        sum1=sum2=0;
        for(int i=1;i<=n-m+1;i++)
        {
            sum1+=(imax[i]^i);
            sum2+=(times[i]^i);
        }
        printf("%lld %lld\n",sum1,sum2);
    }
    return 0;
}

心得:

    好好学算法吧,多接触一些算法,这样做题思路就会宽广,算法不能只接触皮毛,得深入去理解它

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值