GSS1 - Can you answer these queries I(線段樹)
阿新 • • 發佈:2019-01-14
stdin for ref get stdlib.h 中間 you () ==
前言
線段樹菜雞報告,stO ZCDHJ Orz,GSS基本上都切完了。
Solution
考慮一下用線段樹維護一段區間左邊連續的Max,右邊的連續Max,中間的連續Max還有總和,發現這些東西可以相互合並,然後直接寫就好了。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<set> #include<map> #include<iostream> 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; }
GSS1 - Can you answer these queries I(線段樹)