线段树求最大子列。陈老师的代码实在太神了,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 }
View Code

 

posted on 2015-08-13 12:34  onlyRP  阅读(198)  评论(0编辑  收藏  举报