优美的线段树
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cmath> #define MAXN 500000+10 #define ll long long #define pii pair<int,int> #define mp make_pair using namespace std; int a[MAXN]; int n,m; struct Node{ int pre_dat; ll pre_sum; int suf_dat; ll suf_sum; pii dat; ll sum; ll d; Node(int p1=0,ll p2=0,int p3=0,ll p4=0,pii p5=mp(0,0),ll p6=0,ll p7=0){ pre_dat=p1,pre_sum=p2,suf_dat=p3,suf_sum=p4,dat=p5,sum=p6,d=p7; } }data[MAXN<<2]; Node Merge(Node t1,Node t2){ if(t1.dat==mp(0,0))return t2; if(t2.dat==mp(0,0))return t1; Node ret; ret.d=t1.d+t2.d; ret.pre_dat=t1.pre_dat,ret.pre_sum=t1.pre_sum; if(ret.pre_sum<t1.d+t2.pre_sum){ ret.pre_dat=t2.pre_dat,ret.pre_sum=t1.d+t2.pre_sum; } ret.suf_dat=t2.suf_dat,ret.suf_sum=t2.suf_sum; if(ret.suf_sum<=t2.d+t1.suf_sum){ ret.suf_dat=t1.suf_dat,ret.suf_sum=t2.d+t1.suf_sum; } ret.dat=t1.dat,ret.sum=t1.sum; if(ret.sum<t2.sum){ ret.dat=t2.dat,ret.sum=t2.sum; } if(ret.sum<(t1.suf_sum+t2.pre_sum)||ret.sum==(t1.suf_sum+t2.pre_sum)&&ret.dat>mp(t1.suf_dat,t2.pre_dat)){ ret.dat=mp(t1.suf_dat,t2.pre_dat), ret.sum=(t1.suf_sum+t2.pre_sum); } return ret; } void build(int k,int L,int R){ if(L+1==R){ data[k].pre_dat=data[k].suf_dat=L; data[k].dat=mp(L,L); data[k].d=data[k].pre_sum=data[k].suf_sum=data[k].sum=a[L]; return; } build(k<<1,L,(L+R)>>1); build(k<<1|1,(L+R)>>1,R); data[k]=Merge(data[k<<1],data[k<<1|1]); } Node query(int a,int b,int k,int L,int R){ if(b<=L||R<=a){ return Node(0,0,0,0,mp(0,0),0,0); } else if(a<=L&&R<=b){ return data[k]; } else{ int mid=((L+R)>>1); Node lc=query(a,b,k<<1,L,mid); Node rc=query(a,b,k<<1|1,mid,R); return Merge(lc,rc); } } void solve(){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n+1); while(m--){ int x,y; scanf("%d%d",&x,&y); Node ans=query(x,y+1,1,1,n+1); printf("%d %d\n",ans.dat.first,ans.dat.second); } } int main() { // freopen("data.in","r",stdin); // freopen("my.out","w",stdout); int T=0; while(~scanf("%d%d",&n,&m)){ printf("Case %d:\n",++T); solve(); } return 0; }
时间: 2024-10-14 23:59:02