P1427 小白逛公园
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。
一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。
那么,就请你来帮小白选择公园吧。
一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。
那么,就请你来帮小白选择公园吧。
输入格式
第一行,两个整数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的整数。
接下来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的整数。
输出格式
小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。
测试样例1
输入
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3
输出
2
-1
【题解】
线段树裸题,维护前缀最大,后缀最大,最大子区间和区间和
查询的是偶发,维护 当前区间在查询区间范围内的 前缀最大,后缀最大,最大子区间和区间和
注意这个题,有一种情况,叫l > r,要交换过来(淦淦淦淦淦淦淦淦淦淦淦淦)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #define max(a, b) ((a) > (b) ? (a) :(b)) 6 #define min(a, b) ((a) < (b) ? (a) : (b)) 7 8 inline void read(int &x) 9 { 10 x = 0;char ch = getchar(), c = ch; 11 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 12 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 13 if(c == '-')x = -x; 14 } 15 16 inline void swap(int &a, int &b) 17 { 18 int tmp = a; 19 a = b,b = tmp; 20 } 21 22 const int MAXN = 600000 + 10; 23 const int INF = 0x3f3f3f3f3f3f3f3f; 24 25 int n,m,num[MAXN]; 26 27 int left[MAXN << 2], right[MAXN << 2], sum[MAXN << 2], ma[MAXN << 2]; 28 29 void build(int o = 1, int l = 1, int r = n) 30 { 31 if(l == r) 32 { 33 left[o] = right[o] = sum[o] = ma[o] = num[l]; 34 return; 35 } 36 int mid = (l + r) >> 1; 37 build(o << 1, l, mid); 38 build(o << 1 | 1, mid + 1, r); 39 40 left[o] = max(left[o << 1], sum[o << 1] + left[o << 1 | 1]); 41 right[o] = max(right[o << 1 | 1], sum[o << 1 | 1] + right[o << 1]); 42 ma[o] = max(ma[o << 1], max(ma[o << 1 | 1], right[o << 1] + left[o << 1 | 1])); 43 ma[o] = max(ma[o], max(left[o], right[o])); 44 sum[o] = sum[o << 1] + sum[o << 1 | 1]; 45 } 46 47 void modify(int p, int k, int o = 1, int l = 1, int r = n) 48 { 49 if(l == p && l == r) 50 { 51 left[o] = right[o] = sum[o] = ma[o] = k; 52 return; 53 } 54 int mid = (l + r) >> 1; 55 if(mid >= p)modify(p, k, o << 1, l, mid); 56 else modify(p, k, o << 1 | 1, mid + 1, r); 57 58 left[o] = max(left[o << 1], sum[o << 1] + left[o << 1 | 1]); 59 right[o] = max(right[o << 1 | 1], sum[o << 1 | 1] + right[o << 1]); 60 ma[o] = max(ma[o << 1], max(ma[o << 1 | 1], right[o << 1] + left[o << 1 | 1])); 61 ma[o] = max(ma[o], max(left[o], right[o])); 62 sum[o] = sum[o << 1] + sum[o << 1 | 1]; 63 } 64 65 struct Node 66 { 67 int left, right, ma, sum; 68 Node(int _left, int _right, int _ma, int _sum){left = _left, right = _right, ma = _ma, sum = _sum;} 69 Node(){left = right = ma = -INF;sum = 0;} 70 }; 71 72 Node ask(int ll, int rr, int o = 1, int l = 1, int r = n) 73 { 74 if(ll <= l && rr >= r)return Node(left[o], right[o], ma[o], sum[o]); 75 int mid = (l + r) >> 1; 76 Node re, ans1, ans2; 77 int flag1 = 0, flag2 = 0; 78 if(mid >= ll)ans1 = ask(ll, rr, o << 1, l, mid), flag1 = 1; 79 if(mid < rr)ans2 = ask(ll, rr, o << 1 | 1, mid + 1, r), flag2 = 1; 80 81 re.left = max(ans1.left, ans1.sum + ans2.left); 82 if(!flag1) re.left = max(re.left, ans2.left); 83 84 re.right = max(ans2.right, ans2.sum + ans1.right); 85 if(!flag2) re.right = max(ans2.right, re.right); 86 87 re.ma = max(re.left, max(re.right, ans1.right + ans2.left)); 88 re.ma = max(re.ma, max(ans1.ma, ans2.ma)); 89 re.sum = ans1.sum + ans2.sum; 90 return re; 91 } 92 93 int main() 94 { 95 read(n), read(m); 96 for(register int i = 1;i <= n;++ i) read(num[i]); 97 memset(left, -0x3f, sizeof(left)); 98 memset(right, -0x3f, sizeof(left)); 99 memset(ma, -0x3f, sizeof(left)); 100 build(1,1,n); 101 register int tmp1,tmp2,tmp3; 102 register Node tmp; 103 for(register int i = 1;i <= m;++ i) 104 { 105 read(tmp1), read(tmp2), read(tmp3); 106 if(tmp1 == 1) 107 { 108 if(tmp2 > tmp3)swap(tmp2, tmp3); 109 tmp = ask(tmp2, tmp3, 1, 1, n); 110 printf("%d ", tmp.ma); 111 } 112 else modify(tmp2, tmp3, 1, 1, n); 113 } 114 return 0; 115 }