zoukankan      html  css  js  c++  java
  • NOI2010 超级钢琴

    传送门

    Description:

    给定一个序列,求前k大区间和

    Solution:

    我们用f(i,l,r)表示左端点为i,右端点在[l,r]的最大区间和

    设右端点在k时区间和最大 区间和为s[k]-s[i-1]

    由于s[i-1]是确定的 我们只要求出最大的s[k]即可

    即区间最值 可以用ST表求

    这样我们可以[1,n]的每个点作为起点的最大区间和

    但是有两个问题:1 这样求出的区间和并不一定都是最优的

            可能以一个点为左端点的次优解比以另外一个点为左端点的最优解还要优

            2 这样求出的区间和可能不够k个

    其实问题就是我们想要求出一些以某点为左端点的次优解并且加入优先队列得出总体最优解

    以(i,l,r,k)为四元组加入优先队列(含义见上)

    取出优先队列的top 接着把(i,l,k-1,pos),(i,k+1,r,pos)加入优先队列 他们都有可能成为下一个top

    这里的pos用ST表求解即可 所以在记录值时还要记录位置(就是code里的id[])

    CODE

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<queue>
     5 #define Rg register
     6 #define go(i,a,b) for(Rg int i=a;i<=b;i++)
     7 #define ll long long
     8 using namespace std;
     9 int rd()
    10 {
    11     int x=0,y=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    14     return x*y;
    15 }
    16 const int N=500005,T=20;
    17 int n,k,L,R,s[N],f[N][T],id[N][T];
    18 ll ans;
    19 struct node
    20 {
    21     int u,l,r,pos;//u:begin v:[l,r]
    22     bool operator <(node y)const
    23     {
    24         return s[pos]-s[u-1]<s[y.pos]-s[y.u-1];
    25     }
    26 }tmp;
    27 priority_queue<node>q;
    28 void sol(int &pos,int l,int r)
    29 {
    30     int j=log2(r-l+1);
    31     if(f[l][j]>f[r-(1<<j)+1][j]) pos=id[l][j];
    32     else pos=id[r-(1<<j)+1][j];
    33 }
    34 int main()
    35 {
    36     n=rd(),k=rd(),L=rd(),R=rd();
    37     go(i,1,n) s[i]=s[i-1]+rd(),f[i][0]=s[i],id[i][0]=i;
    38     go(j,1,T-1)
    39         go(i,1,n)
    40     {
    41         if(i+(1<<j)-1>n) break;
    42         if(f[i][j-1]>f[i+(1<<j-1)][j-1]) f[i][j]=f[i][j-1],id[i][j]=id[i][j-1];
    43         else f[i][j]=f[i+(1<<j-1)][j-1],id[i][j]=id[i+(1<<j-1)][j-1];
    44     }
    45     go(i,1,n)
    46     {
    47         int l=i+L-1,r=min(i+R-1,n),pos,u=i;
    48         if(i+L-1>n) break;
    49         sol(pos,l,r);tmp=(node){u,l,r,pos};q.push(tmp);
    50     }
    51     while(k--)
    52     {
    53         tmp=q.top();q.pop();
    54         int u=tmp.u,l=tmp.l,r=tmp.r,pos=tmp.pos,tps=pos;
    55         ans+=s[pos]-s[u-1];
    56         if(tps>l)
    57         {sol(pos,l,tps-1);tmp=(node){u,l,tps-1,pos};q.push(tmp);}
    58         if(tps<r)
    59         {sol(pos,tps+1,r);tmp=(node){u,tps+1,r,pos};q.push(tmp);}
    60     }
    61     printf("%lld",ans);
    62     return 0;
    63 }
    View Code
    光伴随的阴影
  • 相关阅读:
    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(转)
    Yii Framework2.0开发教程(5)数据库mysql性能
    假设动态运行java文字,当在脚本式配置,这是非常方便的
    采用jquery的imgAreaSelect样品图像裁剪示范插件实现
    Mybatis 构造resultMap 搜sql
    第13周项目1-动物所谓的
    旋转华尔兹
    馋-c语言的规则
    毕业后的第二份工作:进入国外 在新加坡工作 每月一次18K
    Bringing up interface eth0: Device eth0 does not seem to be present, delaying initialization
  • 原文地址:https://www.cnblogs.com/forward777/p/10375716.html
Copyright © 2011-2022 走看看