Bzoj 1756: Vijos1083 小白逛公园 线段树

1756: Vijos1083 小白逛公园 

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1021  Solved: 326
[Submit][Status][Discuss]

Description

小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。   一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。   那么,就请你来帮小白选择公园吧。 

Input

第一行,两个整数N和M,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。 接下来N行,每行一个整数,依次给出小白 开始时对公园的打分。 接下来M行,每行三个整数。第一个整数K,1或2。K=1表示,小新要带小白出去玩,接下来的两个整数a和b给出了选择公园的范围(1≤a,b≤N);K=2表示,小白改变了对某个公园的打分,接下来的两个整数p和s,表示小白对第p个公园的打分变成了s(1≤p≤N)。 其中,1≤N≤500 000,1≤M≤100 000,所有打分都是绝对值不超过1000的整数。 

Output

小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。 

Sample Input

5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3

Sample Output

2
-1

HINT

 

Source

 题解:
线段树维护。
记得查询时可能覆盖两个区间,所以要传下去结构体。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define MAXN 500010
 4 struct node
 5 {
 6     int left,right,lx,rx,mx,sum;
 7 }tree[5*MAXN];
 8 int a[MAXN];
 9 int read()
10 {
11     int s=0,fh=1;char ch=getchar();
12     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
14     return s*fh;
15 }
16 void Build(int k,int l,int r)
17 {
18     tree[k].left=l;tree[k].right=r;tree[k].sum=0;
19     if(l==r)return;
20     int mid=(l+r)/2;
21     Build(k*2,l,mid);Build(k*2+1,mid+1,r);
22 }
23 void Pushup(int k)
24 {
25     tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
26     tree[k].mx=max(tree[k*2].mx,tree[k*2+1].mx);
27     tree[k].mx=max(tree[k].mx,tree[k*2].rx+tree[k*2+1].lx);
28     tree[k].lx=max(tree[k*2].lx,tree[k*2].sum+tree[k*2+1].lx);
29     tree[k].rx=max(tree[k*2+1].rx,tree[k*2+1].sum+tree[k*2].rx);
30 }
31 void Change(int k,int lr,int C)
32 {
33     if(tree[k].left==tree[k].right){tree[k].sum=tree[k].lx=tree[k].rx=tree[k].mx=C;return;}
34     int mid=(tree[k].left+tree[k].right)/2;
35     if(lr<=mid)Change(k*2,lr,C);
36     else Change(k*2+1,lr,C);
37     Pushup(k);
38 }
39 node Query_max(int k,int l,int r)
40 {
41     if(l<=tree[k].left&&tree[k].right<=r)return tree[k];
42     int mid=(tree[k].left+tree[k].right)/2;
43     if(r<=mid)return Query_max(k*2,l,r);
44     else if(l>mid)return Query_max(k*2+1,l,r);
45     else
46     {
47         node ll,rr,nn;
48         ll=Query_max(k*2,l,mid);rr=Query_max(k*2+1,mid+1,r);
49         nn.sum=ll.sum+rr.sum;
50         nn.mx=max(ll.mx,rr.mx);
51         nn.mx=max(nn.mx,ll.rx+rr.lx);
52         nn.lx=max(ll.lx,ll.sum+rr.lx);
53         nn.rx=max(rr.rx,rr.sum+ll.rx);
54         return nn;
55     }
56 }
57 int main()
58 {
59     int n,m,i,K,A,B;
60     n=read();m=read();
61     for(i=1;i<=n;i++)a[i]=read();
62     Build(1,1,n);
63     for(i=1;i<=n;i++)Change(1,i,a[i]);
64     for(i=1;i<=m;i++)
65     {
66         K=read();A=read();B=read();
67         if(A>B&&K==1)swap(A,B);
68         if(K==1)
69         {
70             node nn;
71             nn=Query_max(1,A,B);
72             printf("%d\n",nn.mx);
73         }
74         else Change(1,A,B);
75     }
76     fclose(stdin);
77     fclose(stdout);
78     return 0;
79 }

 

posted @ 2016-03-24 13:53  微弱的世界  阅读(361)  评论(0编辑  收藏  举报