@yang12138
2018-12-03T06:53:52.000000Z
字数 2149
阅读 1226
未分类
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1053
长度为的整数数列,最多取个不相交子段求和,问和最大是多少?
先把数列中所有去掉,然后把相邻的同号的加起来,这时数列的相邻两个数肯定不同号。对于处理后的数组,把所有正数加到里,设正数的个数有个,如果,那么答案就是,如果,设。
每次取出数列中绝对值最小的数,如果是负数,则视为将其左右两块正数合并,代价是;如果是正数,则视为将这块舍掉,然后和左右两块负数合并,代价也是。重复进行次。
#include <iostream>#include <stdio.h>#include <cstring>#include <algorithm>#include <string>#include <math.h>#include <cstdlib>#include <set>using namespace std;typedef long long ll;typedef pair<ll,int>pii;const int N=1e5+10;ll a[N];int l[N],r[N];struct Node{ll val;int id;Node(){}Node(ll val,int id):val(val),id(id){}bool operator < (const Node& tmp)const{return pii(abs(val),id)<pii(abs(tmp.val),tmp.id);}};void del(int i){l[r[i]]=l[i];r[l[i]]=r[i];}const int BS = 1e7;char buf[BS];char *head,*tail;int flag=0;char getch(){if(head==tail){int len = fread(buf,1,BS,stdin);tail = (head = buf)+len;flag++;if(flag>=2) exit(0);}return *head++;}template<typename T>void scan(T& x){x=0;char ch=getch();while(!(ch=='-' || (ch>='0' && ch<='9'))) ch=getch();bool flag=0;if(ch=='-') flag=1,ch=getch();while(ch>='0' && ch<='9') x=10*x+ch-'0',ch=getch();if(flag) x=-x;}void solve(){int n,tot;scan(n),scan(tot);for(int i=1;i<=n;i++) scan(a[i]);int m=0;for(int i=1;i<=n;i++) if(a[i]!=0) a[++m]=a[i];n=m,m=0;for(int i=1;i<=n;){int j=i;while(j+1<=n && 1LL*a[j+1]*a[j]>0) j++;ll tmp=0;for(int k=i;k<=j;k++) tmp+=a[k];i=j+1,a[++m]=tmp;}n=m;for(int i=0;i<=n;i++) r[i]=i+1;for(int i=1;i<=n+1;i++) l[i]=i-1;set<Node>st;for(int i=1;i<=n;i++){st.insert(Node(a[i],i));if(a[i]>0) tot--;}ll ans=0;for(int i=1;i<=n;i++) if(a[i]>0) ans+=a[i];tot=-tot;while(tot>0){Node u = *st.begin();st.erase(u);if(u.val==0) continue;if(u.val<0){if(l[u.id]==0 || r[u.id]>n) continue;ans-=abs(u.val);ll tval=u.val + a[l[u.id]] + a[r[u.id]];a[u.id]=tval;st.erase(Node(a[l[u.id]],l[u.id]));st.erase(Node(a[r[u.id]],r[u.id]));del(l[u.id]);del(r[u.id]);st.insert(Node(a[u.id],u.id));}else{ans-=abs(u.val);ll tval=u.val;if(l[u.id]!=0){tval += a[l[u.id]];st.erase(Node(a[l[u.id]],l[u.id]));del(l[u.id]);}if(r[u.id]<=n){tval += a[r[u.id]];st.erase(Node(a[r[u.id]],r[u.id]));del(r[u.id]);}a[u.id]=tval;st.insert(Node(a[u.id],u.id));}tot--;}cout<<ans<<endl;}int main(){while(1) solve();return 0;}