• 51nod1053 最大M子段和 V2


    $n leq 50000$的序列,问选不超过$m leq 50000$个区间使得和最大。

    如果正数区间总数比$m$小那肯定全选。否则有两种方式减少区间数量:丢掉一个正区间;补一个负区间连接两个正区间。贪心即可。

    先把左右端的负数去掉,然后把正区间和负区间处理出来。优先队列维护区间值,然后开个链表模拟合并(删左右,改自己)。注意删右边时调整右端点。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<time.h>
      5 //#include<complex>
      6 //#include<set>
      7 #include<queue>
      8 //#include<vector>
      9 #include<algorithm>
     10 #include<stdlib.h>
     11 using namespace std;
     12 
     13 #define LL long long
     14 int qread()
     15 {
     16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     18 }
     19 
     20 //Pay attention to '-' , LL and double of qread!!!!
     21 
     22 int n,m;
     23 #define maxn 50011
     24 #define LL long long
     25 
     26 LL Abs(LL x) {return x>0?x:-x;}
     27 
     28 int a[maxn]; LL sum[maxn];
     29 int b[maxn],lb,ll[maxn],rr[maxn]; bool vis[maxn];
     30 struct qnode
     31 {
     32     LL v; int id;
     33     bool operator > (const qnode &b) const {return v>b.v;}
     34 };
     35 priority_queue<qnode,vector<qnode>,greater<qnode> > q;
     36 int main()
     37 {
     38     n=qread(); m=qread();
     39     for (int i=1;i<=n;i++) a[i]=qread();
     40     {
     41         int L=1,R=n; while (a[L]<=0) L++; while (a[R]<=0) R--;
     42         for (int i=L,j=1;i<=R;i++,j++) a[j]=a[i];
     43         n=R-L+1; a[n+1]=0;
     44     }
     45     for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
     46     
     47     LL ans=0;
     48     int cnt=0;
     49     {
     50         LL tmp=a[1],last=1;
     51         for (int i=2;i<=n+1;i++)
     52         {
     53             if (tmp>0 && a[i]<=0)
     54             {
     55                 b[++lb]=last;
     56                 q.push((qnode){tmp,lb});
     57                 ans+=tmp; cnt++; tmp=a[i]; last=i;
     58             }
     59             else if (tmp>0 && a[i]>0) tmp+=a[i];
     60             else if (tmp<=0 && a[i]>0)
     61             {
     62                 b[++lb]=last;
     63                 q.push((qnode){-tmp,lb});
     64                 tmp=a[i]; last=i;
     65             }
     66             else tmp+=a[i];
     67         }
     68     }
     69     
     70     for (int i=0;i<=lb+1;i++) ll[i]=i-1,rr[i]=i+1; b[lb+1]=n+1;
     71     if (cnt<=m) {printf("%lld
    ",ans); return 0;}
     72     while (m<cnt--)
     73     {
     74         while (vis[q.top().id]) q.pop();
     75         ans-=q.top().v; int now=q.top().id; q.pop();
     76         
     77         if (ll[now]==0)
     78         {
     79             vis[rr[now]]=1;
     80             vis[now]=1;
     81             int u=rr[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
     82             ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
     83         }
     84         else if (rr[now]==lb+1)
     85         {
     86             vis[ll[now]]=1;
     87             vis[now]=1;
     88             int u=ll[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
     89             ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u]; b[lb+1]=b[u];
     90         }
     91         else
     92         {
     93             int L=b[ll[now]],R=b[rr[rr[now]]]-1;
     94             vis[ll[now]]=1; vis[rr[now]]=1; int u=ll[now],v=rr[now];
     95             b[now]=L; q.push((qnode){Abs(sum[R]-sum[L-1]),now});
     96             ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
     97             ll[rr[v]]=ll[v]; rr[ll[v]]=rr[v];
     98         }
     99     }
    100     
    101     printf("%lld
    ",ans);
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    javascript 原型和构造函数
    react native与原生的交互
    项目中git的用法
    web页面的回流,认识与避免
    js 中的算法题,那些经常看到的
    js中this的四种调用模式
    JS面向对象的几种写法
    模块化加载require.js
    es6新语法
    vue组件化开发
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9166635.html
Copyright © 2020-2023  润新知