线段树求最大子列。陈老师的代码实在太神了,orz CLJ!!!!
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(i=l;i<=r;i++) 3 #define dec(i,l,r) for(i=l;i>=r;i--) 4 #define inf 1e9 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define NM 500000+5 7 using namespace std; 8 struct info{ 9 int l,r,s,m; 10 info(int x=0):l(x),r(x),m(x),s(x){ 11 } 12 }none,T[3*NM]; 13 info operator+(const info &x,const info &y){ 14 info f; 15 if(x.l==-inf)return y; 16 if(y.l==-inf)return x; 17 f.l=max(x.l,x.s+y.l); 18 f.r=max(y.r,x.r+y.s); 19 f.s=x.s+y.s; 20 f.m=max(x.m,y.m); 21 f.m=max(f.m,x.r+y.l); 22 return f; 23 } 24 int i,n,m,x,y,a[NM],t; 25 void build(int i,int x,int y){ 26 int t=(x+y)/2; 27 if(x==y){ 28 T[i]=info(a[x]); 29 return; 30 } 31 build(i*2,x,t);build(i*2+1,t+1,y); 32 T[i]=T[i*2]+T[i*2+1]; 33 } 34 info work(int i,int x,int y,int a,int b){ 35 int t=(x+y)/2; 36 if(b<x||a>y)return none; 37 if(a<=x&&y<=b)return T[i]; 38 return work(i*2,x,t,a,b)+work(i*2+1,t+1,y,a,b); 39 } 40 void ch(int i,int x,int y,int a,int b){ 41 int t=(x+y)/2; 42 if(x==y){ 43 T[i]=info(b); 44 return; 45 } 46 if(a<=t)ch(i*2,x,t,a,b); 47 else ch(i*2+1,t+1,y,a,b); 48 T[i]=T[i*2]+T[i*2+1]; 49 } 50 int main(){ 51 scanf("%d%d",&n,&m); 52 none=info(-inf); 53 inc(i,1,n)scanf("%d",a+i); 54 build(1,1,n); 55 inc(i,1,m){ 56 scanf("%d%d%d",&t,&x,&y); 57 if(t==1){ 58 if(x>y)swap(x,y); 59 printf("%d\n",work(1,1,n,x,y).m); 60 }else ch(1,1,n,x,y); 61 } 62 return 0; 63 }