本文共 1691 字,大约阅读时间需要 5 分钟。
线段树菜鸡报告,stO Orz,GSS基本上都切完了。
考虑一下用线段树维护一段区间左边连续的Max,右边的连续Max,中间的连续Max还有总和,发现这些东西可以相互合并,然后直接写就好了。
#include #include #include #include #include #include #include #include #include using namespace std;#define ll long long#define re register#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)inline int gi(){ int f=1,sum=0;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return f*sum;}const int N=50010;int a[N];struct node{ int sum,ls,rs,ts;}t[N<<4];void pushup(int o){ t[o].sum=t[o<<1].sum+t[o<<1|1].sum; t[o].ts=max(t[o<<1].ts,max(t[o<<1|1].ts,t[o<<1].rs+t[o<<1|1].ls)); t[o].ls=max(t[o<<1].ls,t[o<<1].sum+t[o<<1|1].ls); t[o].rs=max(t[o<<1|1].rs,t[o<<1].rs+t[o<<1|1].sum);}void build(int o,int l,int r){ if(l==r){t[o].ls=t[o].rs=t[o].ts=t[o].sum=a[l];return;} int mid=(l+r)>>1; build(o<<1,l,mid);build(o<<1|1,mid+1,r); pushup(o);}node query(int o,int l,int r,int posl,int posr){ if(posl<=l && r<=posr)return t[o]; int mid=(l+r)>>1; if(posl>mid)return query(o<<1|1,mid+1,r,posl,posr); if(posr<=mid)return query(o<<1,l,mid,posl,posr); else{ node ans,a,b; a=query(o<<1,l,mid,posl,mid);b=query(o<<1|1,mid+1,r,mid+1,posr); ans.sum=a.sum+b.sum; ans.ts=max(a.ts,max(b.ts,a.rs+b.ls)); ans.ls=max(a.ls,a.sum+b.ls); ans.rs=max(b.rs,a.rs+b.sum); return ans; }}int main(){ int n=gi(); for(int i=1;i<=n;i++)a[i]=gi(); build(1,1,n);int m=gi(); while(m--){ int l=gi(),r=gi(); printf("%d\n",query(1,1,n,l,r).ts); } return 0;}
转载于:https://www.cnblogs.com/mle-world/p/10264103.html