• HDU3145 Max Sum of Max-K-sub-sequence (单调队列模板)


    如何学过单调队列就能发现是裸题,因为题目求的是最大子序和,而我们发现就是跟前缀和相关,也就是说对每个点找到最小前缀和

    这里因为是环,所以破环成链,但是这样会导致结束坐标可能超过n,只要%n即可,开始坐标不可能超过n,因为超过n跟从头开始是一样的,所以不会更新到

    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=2e6+7;
    const int inf=0x3f3f3f3f;
    int a[N];
    int q[N];
    int s[N];
    int main(){
        int t;
        cin>>t;
        while(t--){
        int n,k;
        cin>>n>>k;
        int i,j;
        memset(s,0,sizeof s);
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            s[i]=s[i+n]=a[i];
        }
        for(i=1;i<=2*n;i++)
            s[i]+=s[i-1];
        int hh=0;
        int tt=0;
        q[0]=0;
        int res=-0x3f3f3f3f;
        int pos=0;
        int ed=0;
        for(i=1;i<=2*n;i++){
            while(hh<=tt&&q[hh]<i-k)
                hh++;
            if(s[i]-s[q[hh]]>res){
                res=s[i]-s[q[hh]];
                pos=q[hh]+1;
                ed=i;
            }
            else if(s[i]-s[q[hh]]==res){
                if(pos>q[hh]+1){
                    pos=q[hh]+1;
                    ed=i;
                }
                else if(pos==q[hh]+1){
                    if(i<ed)
                    ed=i;
                }
            }
            while(hh<=tt&&s[q[tt]]>=s[i])
                tt--;
            q[++tt]=i;
        }
        if(ed>n)
            ed-=n;
        cout<<res<<" "<<pos<<" "<<ed<<endl;
        }
    
    }
    View Code
  • 相关阅读:
    mysql innodb myisam 主要区别与更改方法
    oracle双机热备概念
    oracle 查询死锁 kill 会话进程
    数据库触发器new old
    openssh 7.1升级方式
    GoldPoint(结队编程)
    四则运算
    自我介绍及目标
    WorldCount项目
    企业级应用与互联网应用的区别以及Java EE思维导图
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12459471.html
Copyright © 2020-2023  润新知