TYVJ1427 小白逛公园

P1427 小白逛公园
时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

    小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。
    一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第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的整数。

输出格式

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

测试样例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\n", tmp.ma);
111         }
112         else modify(tmp2, tmp3, 1, 1, n);
113     }
114     return 0;
115 } 
TYVJ1427

 

posted @ 2017-09-06 08:52  嘒彼小星  阅读(169)  评论(0编辑  收藏  举报