GSS1

线段树最大子段和裸题,不带修改,注意pushup。

然而并不会猫树之类的东西

 1 #include<bits/stdc++.h>
 2 #define MAXN 50001
 3 using namespace std;
 4 struct node{
 5     int l , r , sum , lMax , rMax , midMax;
 6 }Tree[MAXN << 2];
 7 int a[MAXN] , rMax , allMax , N;
 8
 9 inline int max(int a , int b){
10     return a > b ? a : b;
11 }
12
13 void init(int dir , int l , int r){
14     Tree[dir].l = l;
15     Tree[dir].r = r;
16     if(l == r)
17         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = Tree[dir].sum = a[l];
18     else{
19         init(dir << 1 , l , (l + r) >> 1);
20         init(dir << 1 | 1 , ((l + r) >> 1) + 1 , r);
21         Tree[dir].sum = Tree[dir << 1].sum + Tree[dir << 1 | 1].sum;
22            Tree[dir].lMax = max(Tree[dir << 1].lMax , Tree[dir << 1].sum + Tree[dir << 1 | 1].lMax);
23         Tree[dir].rMax = max(Tree[dir << 1 | 1].rMax , Tree[dir << 1 | 1].sum + Tree[dir << 1].rMax);
24         Tree[dir].midMax = max(max(Tree[dir << 1].midMax , Tree[dir << 1 | 1].midMax) , Tree[dir << 1].rMax + Tree[dir << 1 | 1].lMax);
25     }
26 }
27
28 void findMax(int dir , int l , int r){
29     if(Tree[dir].l >= l && Tree[dir].r <= r){
30         allMax = max(allMax , max(rMax + Tree[dir].lMax , Tree[dir].midMax));
31         rMax = max(max(Tree[dir].rMax , Tree[dir].sum + rMax) , 0);
32         return;
33     }
34     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
35         findMax(dir << 1 , l , r);
36     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
37         findMax(dir << 1 | 1 , l , r);
38 }
39
40 inline void work(int x , int y){
41     allMax = -0x7fffffff;
42     rMax = 0;
43     findMax(1 , x , y);
44     printf("%d\n" , allMax);
45 }
46
47 int main(){
48     scanf("%d" , &N);
49     for(int i = 1 ; i <= N ; i++)
50         scanf("%d" , a + i);
51     init(1 , 1 , N);
52     int T;
53     for(scanf("%d" , &T) ; T ; T--){
54         int a , b;
55         scanf("%d%d" , &a , &b);
56         work(a , b);
57     }
58     return 0;
59 }

GSS1

GSS2

因为不是传统的最大子段和所以单独开了一页:Sol

GSS3

带修改的GSS1

其实也没什么区别只是莫名代码长了很多

 1 #include<bits/stdc++.h>
 2 #define MAXN 50001
 3 #define ll long long
 4 using namespace std;
 5 inline ll read(){
 6     ll a = 0;
 7     char c = getchar();
 8     bool f = 0;
 9     while(!isdigit(c)){
10         if(c == '-')    f = 1;
11         c = getchar();
12     }
13     while(isdigit(c))    a = (a << 3) + (a << 1) + (c ^ '0') , c = getchar();
14     return f ? -a : a;
15 }
16
17 inline void print(ll x){
18     int num[21] , dirN = 0;
19     if(x < 0){
20         putchar('-');
21         x = -x;
22     }
23     while(x){
24         num[dirN++] = x % 10;
25         x /= 10;
26     }
27     if(dirN == 0)    putchar('0');
28     while(dirN)    putchar(num[--dirN] + 48);
29     putchar('\n');
30 }
31
32 struct node{
33     ll l , r , lMax , rMax , sum , midMax;
34 }Tree[MAXN << 2];
35 ll num[MAXN] , N , nowMaxLeft , nowMax;
36
37 inline ll max(ll a , ll b){return a > b ? a : b;}
38
39 void build(ll dir , ll l , ll r){
40     Tree[dir].l = l;    Tree[dir].r = r;
41     if(l == r)
42         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = Tree[dir].sum = num[l];
43     else{
44         build(dir << 1 , l , l + r >> 1);
45         build(dir << 1 | 1 , (l + r >> 1) + 1 , r);
46         Tree[dir].lMax = max(Tree[dir << 1].sum + Tree[dir << 1 | 1].lMax , Tree[dir << 1].lMax);
47         Tree[dir].rMax = max(Tree[dir << 1 | 1].sum + Tree[dir << 1].rMax , Tree[dir << 1 | 1].rMax);
48         Tree[dir].sum = Tree[dir << 1].sum + Tree[dir << 1 | 1].sum;
49         Tree[dir].midMax = max(Tree[dir << 1 | 1].lMax + Tree[dir << 1].rMax , max(Tree[dir << 1].midMax , Tree[dir << 1 | 1].midMax));
50     }
51 }
52
53 void change(ll dir , ll a , ll b){
54     if(Tree[dir].l == a && Tree[dir].r == a){
55         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = Tree[dir].sum = b;
56         return;
57     }
58     if(a > Tree[dir].l + Tree[dir].r >> 1)    change(dir << 1 | 1 , a , b);
59     else    change(dir << 1 , a , b);
60     Tree[dir].lMax = max(Tree[dir << 1].sum + Tree[dir << 1 | 1].lMax , Tree[dir << 1].lMax);
61     Tree[dir].rMax = max(Tree[dir << 1 | 1].sum + Tree[dir << 1].rMax , Tree[dir << 1 | 1].rMax);
62     Tree[dir].sum = Tree[dir << 1].sum + Tree[dir << 1 | 1].sum;
63     Tree[dir].midMax = max(Tree[dir << 1 | 1].lMax + Tree[dir << 1].rMax , max(Tree[dir << 1].midMax , Tree[dir << 1 | 1].midMax));
64 }
65
66 void findMax(ll dir , ll a , ll b){
67     if(Tree[dir].l >= a && Tree[dir].r <= b){
68         nowMax = max(nowMax , max(max(nowMaxLeft , 0) + Tree[dir].lMax , Tree[dir].midMax));
69         nowMaxLeft = max(nowMaxLeft + Tree[dir].sum , Tree[dir].rMax);
70         return;
71     }
72     if(a <= Tree[dir].l + Tree[dir].r >> 1)    findMax(dir << 1 , a , b);
73     if(b > Tree[dir].l + Tree[dir].r >> 1)    findMax(dir << 1 | 1 , a , b);
74 }
75
76 int main(){
77     N = read();
78     for(register int i = 1 ; i <= N ; i++)    num[i] = read();
79     build(1 , 1 , N);
80     register int a , b , M = read();
81     while(M--)
82         if(read() == 1){
83             a = read();    b = read();
84             nowMaxLeft = nowMax = -0x7f7f7f7f;
85             findMax(1 , a , b);
86             print(max(nowMax , nowMaxLeft));
87         }
88         else{
89             a = read();    b = read();
90             change(1 , a , b);
91         }
92     return 0;
93 }

GSS3

GSS4

话说这东西似乎叫做势能线段树?

$10^{18}$开$6-7$次根就会变成$1$,而$\sqrt{1} = 1$,所以我们可以建一棵这样子的线段树:最开始几次修改暴力到叶子节点进行修改,在之后的某一次修改中,如果某一个节点所表示的区间中所有数就变成了$1$,就不往下走

 1 #include<bits/stdc++.h>
 2 #define MAXN 100010
 3 #define int unsigned long long
 4 using namespace std;
 5
 6 inline int read(){
 7     int a = 0;
 8     char c = getchar();
 9     while(c != EOF && !isdigit(c))
10         c = getchar();
11     while(c != EOF && isdigit(c)){
12         a = (a << 3) + (a << 1) + (c ^ '0');
13         c = getchar();
14     }
15     return a;
16 }
17
18 struct node{
19     int sum;
20     bool f;
21 }Tree[MAXN << 2];
22
23 inline void pushup(int now){
24     Tree[now].sum = Tree[now << 1].sum + Tree[now << 1 | 1].sum;
25     Tree[now].f = Tree[now << 1].f && Tree[now << 1 | 1].f;
26 }
27
28 void init(int now , int l , int r){
29     if(l == r){
30         Tree[now].sum = read();
31         Tree[now].f = Tree[now].sum == 1;
32         return;
33     }
34     init(now << 1 , l , l + r >> 1);
35     init(now << 1 | 1 , (l + r >> 1) + 1 , r);
36     pushup(now);
37 }
38
39 void change(int now , int l , int r , int L , int R){
40     if(Tree[now].f)
41         return;
42     if(l == r){
43         Tree[now].sum = sqrt(Tree[now].sum);
44         Tree[now].f = Tree[now].sum == 1;
45         return;
46     }
47     if(l + r >> 1 >= L)
48         change(now << 1 , l , l + r >> 1 , L , R);
49     if(l + r >> 1 < R)
50         change(now << 1 | 1 , (l + r >> 1) + 1 , r , L , R);
51     pushup(now);
52 }
53
54 int getAns(int now , int l , int r , int L , int R){
55     if(l >= L && r <= R)
56         return Tree[now].sum;
57     int sum = 0;
58     if(l + r >> 1 >= L)
59         sum += getAns(now << 1 , l , l + r >> 1 , L , R);
60     if(l + r >> 1 < R)
61         sum += getAns(now << 1 | 1 , (l + r >> 1) + 1 , r , L , R);
62     return sum;
63 }
64
65 main()
66 {
67     ios::sync_with_stdio(0);
68     cin.tie(0);
69     cout.tie(0);
70     int N , c = 0;
71     while((N = read()) && N){
72         init(1 , 1 , N);
73         cout << "Case #" << ++c << ":" << endl;
74         for(int M = read() ; M ; M--)
75             if(read() == 0){
76                 int a = read() , b = read();
77                 if(a > b)
78                     swap(a , b);
79                 change(1 , 1 , N , a , b);
80             }
81             else{
82                 int a = read() , b = read();
83                 if(a > b)
84                     swap(a , b);
85                 cout << getAns(1 , 1 , N , a , b) << endl;
86             }
87         cout << endl;
88      }
89      return 0;
90 }

GSS4

GSS5

设左区间为$[a,b]$,右区间为$[c,d]$,满足$b \geq c$

分类讨论:

①左端点在$[a,c)$,答案为$[a,c)$的最大后缀与$[c,d]$的最大前缀

②右端点在$(b,d]$,答案为$[a,b]$的最大后缀与$(b,d]$的最大前缀

③左右端点都在$[b,c]$,答案为$[b,c]$的最大子段和

  1 #include<bits/stdc++.h>
  2 #define MAXN 10001
  3 using namespace std;
  4
  5 inline int max(int a , int b){
  6     return a > b ? a : b;
  7 }
  8 inline int min(int a , int b){
  9     return a < b ? a : b;
 10 }
 11
 12 struct node{
 13     int l , r , lMax , rMax , midMax , sum;
 14 }Tree[MAXN << 2];
 15 int a[MAXN] , N , lMax , rMax , allMax;
 16
 17 void init(int dir , int l , int r){
 18     Tree[dir].l = l;
 19     Tree[dir].r = r;
 20     if(l == r)
 21         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = Tree[dir].sum = a[l];
 22     else{
 23         init(dir << 1 , l , (l + r) >> 1);
 24         init(dir << 1 | 1 , ((l + r) >> 1) + 1 , r);
 25         Tree[dir].sum = Tree[dir << 1].sum + Tree[dir << 1 | 1].sum;
 26         Tree[dir].lMax = max(Tree[dir << 1].lMax , Tree[dir << 1].sum + Tree[dir << 1 | 1].lMax);
 27         Tree[dir].rMax = max(Tree[dir << 1 | 1].rMax , Tree[dir << 1].rMax + Tree[dir << 1 | 1].sum);
 28         Tree[dir].midMax = max(Tree[dir << 1].rMax + Tree[dir << 1 | 1].lMax , max(Tree[dir << 1].midMax , Tree[dir << 1 | 1].midMax));
 29     }
 30 }
 31
 32 int findSum(int dir , int l , int r){
 33     if(Tree[dir].l >= l && Tree[dir].r <= r)
 34         return Tree[dir].sum;
 35     int sum = 0;
 36     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
 37         sum += findSum(dir << 1 , l , r);
 38     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
 39         sum += findSum(dir << 1 | 1 , l , r);
 40     return sum;
 41 }
 42
 43 void findRightMax(int dir , int l , int r){
 44     if(Tree[dir].l >= l && Tree[dir].r <= r){
 45         allMax = max(allMax , Tree[dir].rMax + rMax);
 46         rMax += Tree[dir].sum;
 47         return;
 48     }
 49     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
 50         findRightMax(dir << 1 | 1 , l , r);
 51     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
 52         findRightMax(dir << 1 , l , r);
 53 }
 54
 55 void findLeftMax(int dir , int l , int r){
 56     if(Tree[dir].l >= l && Tree[dir].r <= r){
 57         allMax = max(allMax , Tree[dir].lMax + lMax);
 58         lMax += Tree[dir].sum;
 59         return;
 60     }
 61     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
 62         findLeftMax(dir << 1 , l , r);
 63     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
 64         findLeftMax(dir << 1 | 1 , l , r);
 65 }
 66
 67 void findMax(int dir , int l , int r){
 68     if(Tree[dir].l >= l && Tree[dir].r <= r){
 69         allMax = max(allMax , max(Tree[dir].lMax + rMax , Tree[dir].midMax));
 70         rMax = max(0 , max(Tree[dir].sum + rMax , Tree[dir].rMax));
 71         return;
 72     }
 73     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
 74         findMax(dir << 1 , l , r);
 75     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
 76         findMax(dir << 1 | 1 , l , r);
 77 }
 78
 79 inline int getAns(int a , int b , int c , int d){
 80     int t = 0;
 81     if(b + 1 < c)
 82         t += findSum(1 , b + 1 , c - 1);
 83     if(a <= b){
 84         allMax = -0x7fffffff;
 85         rMax = 0;
 86         findRightMax(1 , a , b);
 87         t += allMax;
 88     }
 89     if(c <= d){
 90         allMax = -0x7fffffff;
 91         lMax = 0;
 92         findLeftMax(1 , c , d);
 93         t += allMax;
 94     }
 95     return t;
 96 }
 97
 98 inline int work(int a , int b , int c , int d){
 99     c = max(a , c);
100     b = min(b , d);
101     if(b < c)
102         return getAns(a , b , c , d);
103     else{
104         allMax = -0x7fffffff;
105         rMax = 0;
106         findMax(1 , c , b);
107         int t = allMax;
108         return max(max(getAns(a , c - 1 , c , d) , getAns(c , b , b + 1 , d)) , t);
109     }
110 }
111
112 int main(){
113     int T;
114     for(cin >> T ; T ; T--){
115         cin >> N;
116         for(int i = 1 ; i <= N ; i++)
117             cin >> a[i];
118         init(1 , 1 , N);
119         int M;
120         for(cin >> M ; M ; M--){
121             int a , b , c , d;
122             cin >> a >> b >> c >> d;
123             printf("%d\n" , work(a , b , c , d));
124         }
125     }
126     return 0;
127 }

GSS5

GSS6

维护数列削弱版本

因为$remove$的一个智障失误调了$3h$

  1 #include<bits/stdc++.h>
  2 #define root Tree[0].ch[0]
  3 #define lch Tree[x].ch[0]
  4 #define rch Tree[x].ch[1]
  5 #define INF 0x3f3f3f3f
  6 //This code is written by Itst
  7 using namespace std;
  8
  9 inline int max(int a , int b){
 10     return a > b ? a : b;
 11 }
 12
 13 inline int min(int a , int b){
 14     return a < b ? a : b;
 15 }
 16
 17 inline int read(){
 18     int a = 0;
 19     bool f = 0;
 20     char c = getchar();
 21     while(c != EOF && !isdigit(c)){
 22         if(c == '-')
 23             f = 1;
 24         c = getchar();
 25     }
 26     while(c != EOF && isdigit(c)){
 27         a = (a << 3) + (a << 1) + (c ^ '0');
 28         c = getchar();
 29     }
 30     return f ? -a : a;
 31 }
 32
 33 char output[21];
 34 inline void print(int x){
 35     if(x < 0){
 36         putchar('-');
 37         x = -x;
 38     }
 39     if(!x)
 40         putchar('0');
 41     int dirN = 0;
 42     while(x){
 43         output[dirN++] = x % 10 + 48;
 44         x /= 10;
 45     }
 46     while(dirN)
 47         putchar(output[--dirN]);
 48     putchar('\n');
 49 }
 50
 51 const int MAXN = 200003;
 52 struct node{
 53     int fa , size , ch[2] , allMax , lMax , rMax , val , sum;
 54 }Tree[MAXN];
 55 int num[MAXN] , N , cntNode , y , z , w;
 56
 57 inline bool son(const int& x){
 58     return Tree[Tree[x].fa].ch[1] == x;
 59 }
 60
 61 void pushup(int x){
 62     Tree[x].lMax = max(Tree[lch].lMax , Tree[lch].sum + Tree[x].val + max(Tree[rch].lMax , 0));
 63     Tree[x].rMax = max(Tree[rch].rMax , Tree[rch].sum + Tree[x].val + max(Tree[lch].rMax , 0));
 64     Tree[x].allMax = max(max(Tree[lch].allMax , Tree[rch].allMax) , max(Tree[lch].rMax , 0) + max(Tree[rch].lMax , 0) + Tree[x].val);
 65     Tree[x].sum = Tree[lch].sum + Tree[rch].sum + Tree[x].val;
 66     Tree[x].size = Tree[lch].size + Tree[rch].size + 1;
 67 }
 68
 69 inline void ZigZag(int x){
 70     bool f = son(x);
 71     y = Tree[x].fa;
 72     z = Tree[y].fa;
 73     w = Tree[x].ch[f ^ 1];
 74     Tree[z].ch[son(y)] = x;
 75     Tree[x].fa = z;
 76     Tree[x].ch[f ^ 1] = y;
 77     Tree[y].fa = x;
 78     Tree[y].ch[f] = w;
 79     if(w)
 80         Tree[w].fa = y;
 81     pushup(y);
 82 }
 83
 84 inline void Splay(int x , int tar){
 85     while(Tree[x].fa != tar){
 86         if(Tree[Tree[x].fa].fa != tar)
 87             ZigZag(son(x) == son(Tree[x].fa) ? Tree[x].fa : x);
 88         ZigZag(x);
 89     }
 90     pushup(x);
 91 }
 92
 93 void insert(int& x , int fa , int rk , int val){
 94     if(!x){
 95         x = ++cntNode;
 96         Tree[x].fa = fa;
 97         Tree[x].lMax = Tree[x].rMax = Tree[x].allMax = Tree[x].val = Tree[x].sum = val;
 98         Tree[x].size = 1;
 99         Splay(x , 0);
100         return;
101     }
102     if(rk > Tree[lch].size)
103         insert(rch , x , rk - Tree[lch].size - 1 , val);
104     else
105         insert(lch , x , rk , val);
106 }
107
108 void getKth(int x , int rk , int tar){
109     if(rk == Tree[lch].size)
110         Splay(x , tar);
111     else
112         if(rk > Tree[lch].size)
113             getKth(rch , rk - Tree[lch].size - 1 , tar);
114         else
115             getKth(lch , rk , tar);
116 }
117
118 inline void remove(int rk){
119     getKth(root , rk , 0);
120     getKth(root , rk - 1 , root);
121     int t = root;
122     root = Tree[t].ch[0];
123     Tree[root].ch[1] = Tree[t].ch[1];
124     Tree[root].fa = 0;
125     Tree[Tree[t].ch[1]].fa = root;
126     pushup(Tree[t].ch[0]);
127 }
128
129 inline void change(int rk , int val){
130     getKth(root , rk , 0);
131     Tree[root].val = val;
132     pushup(root);
133 }
134
135 inline void query(int l , int r){
136     getKth(root , l - 1 , 0);
137     getKth(root , r + 1 , root);
138     print(Tree[Tree[Tree[root].ch[1]].ch[0]].allMax);
139 }
140
141 inline char getc(){
142     char c = getchar();
143     while(!isupper(c))
144         c = getchar();
145     return c;
146 }
147
148 int main(){
149 #ifndef ONLINE_JUDGE
150     freopen("4487.in" , "r" , stdin);
151     freopen("4487.out" , "w" , stdout);
152 #endif
153     insert(root , 0 , 0 , 0);
154     insert(root , 0 , 1 , 0);
155     Tree[1].allMax = Tree[2].allMax = Tree[0].allMax = -INF;
156     N = read();
157     for(int i = 1 ; i <= N ; ++i)
158         insert(root , 0 , i , read());
159     int a , b;
160     for(register int M = read() ; M ; --M){
161         if(Tree[0].fa)
162             Tree[0].fa = 0;
163         switch(getc()){
164         case 'I':
165             a = read();
166             b = read();
167             insert(root , 0 , a , b);
168             break;
169         case 'D':
170             remove(read());
171             break;
172         case 'R':
173             a = read();
174             b = read();
175             change(a , b);
176             break;
177         case 'Q':
178             a = read();
179             b = read();
180             query(a , b);
181             break;
182         }
183     }
184     return 0;
185 }

GSS6

GSS7

树剖+最大子段和

实际上也没什么区别只是莫名码量大了非常多

  1 #include<bits/stdc++.h>
  2 #define MAXN 100001
  3 using namespace std;
  4 inline int read(){
  5     int a = 0;
  6     bool f = 0;
  7     char c = getchar();
  8     while(!isdigit(c)){
  9         if(c == '-')
 10             f = 1;
 11         c = getchar();
 12     }
 13     while(isdigit(c)){
 14         a = (a << 3) + (a << 1) + (c ^ '0');
 15         c = getchar();
 16     }
 17     return f ? -a : a;
 18 }
 19 char output[12];
 20 inline void print(int x){
 21     int dirN = 11;
 22     if(x == 0)
 23         fwrite("0" , sizeof(char) , 1 , stdout);
 24     else{
 25         if(x < 0){
 26             x = -x;
 27             fwrite("-" , sizeof(char) , 1 , stdout);
 28         }
 29         while(x){
 30                output[--dirN] = x % 10 + 48;
 31             x /= 10;
 32         }
 33         fwrite(output + dirN , 1 , strlen(output + dirN) , stdout);
 34     }
 35     fwrite("\n" , 1 , 1 , stdout);
 36 }
 37
 38 struct node{
 39     int l , r , lMax , rMax , midMax , sum , mark;
 40 }Tree[MAXN << 2];
 41 struct Edge{
 42     int end , upEd;
 43 }Ed[MAXN << 1];
 44 int val[MAXN] , head[MAXN] , size[MAXN] , son[MAXN] , fa[MAXN] , dep[MAXN];
 45 int top[MAXN] , ind[MAXN] , rk[MAXN] , N , ts , cntEd , allMax , lMax , rMax;
 46
 47 inline void addEd(int a , int b){
 48     Ed[++cntEd].end = b;
 49     Ed[cntEd].upEd = head[a];
 50     head[a] = cntEd;
 51 }
 52
 53 void dfs1(int dir , int father){
 54     size[dir] = 1;
 55     dep[dir] = dep[fa[dir] = father] + 1;
 56     for(int i = head[dir] ; i ; i = Ed[i].upEd)
 57         if(!dep[Ed[i].end]){
 58             dfs1(Ed[i].end , dir);
 59             size[dir] += size[Ed[i].end];
 60             if(size[son[dir]] < size[Ed[i].end])
 61                 son[dir] = Ed[i].end;
 62         }
 63 }
 64
 65 void dfs2(int dir , int t){
 66     top[dir] = t;
 67     rk[ind[dir] = ++ts] = dir;
 68     if(!son[dir])
 69         return;
 70     dfs2(son[dir] , t);
 71     for(int i = head[dir] ; i ; i = Ed[i].upEd)
 72         if(Ed[i].end != son[dir] && Ed[i].end != fa[dir])
 73             dfs2(Ed[i].end , Ed[i].end);
 74 }
 75
 76 inline void pushup(int dir){
 77     Tree[dir].lMax = max(Tree[dir << 1].lMax , Tree[dir << 1].sum + Tree[dir << 1 | 1].lMax);
 78     Tree[dir].rMax = max(Tree[dir << 1 | 1].rMax , Tree[dir << 1].rMax + Tree[dir << 1 | 1].sum);
 79     Tree[dir].sum = Tree[dir << 1].sum + Tree[dir << 1 | 1].sum;
 80     Tree[dir].midMax = max(max(Tree[dir << 1].midMax , Tree[dir << 1 | 1].midMax) , Tree[dir << 1].rMax + Tree[dir << 1 | 1].lMax);
 81 }
 82
 83 inline void pushdown(int dir){
 84     if(Tree[dir].mark != -10001){
 85         Tree[dir << 1].lMax = Tree[dir << 1].rMax = Tree[dir << 1].midMax = max(Tree[dir << 1].sum = Tree[dir].mark * (Tree[dir << 1].r - Tree[dir << 1].l + 1) , 0);
 86         Tree[dir << 1 | 1].lMax = Tree[dir << 1 | 1].rMax = Tree[dir << 1 | 1].midMax = max(Tree[dir << 1 | 1].sum = Tree[dir].mark * (Tree[dir << 1 | 1].r - Tree[dir << 1 | 1].l + 1) , 0);
 87         Tree[dir << 1].mark = Tree[dir << 1 | 1].mark = Tree[dir].mark;
 88         Tree[dir].mark = -10001;
 89     }
 90 }
 91
 92 void init(int dir , int l , int r){
 93     Tree[dir].l = l;
 94     Tree[dir].r = r;
 95     Tree[dir].mark = -10001;
 96     if(l == r)
 97         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = max(Tree[dir].sum = val[rk[l]] , 0);
 98     else{
 99         init(dir << 1 , l , (l + r) >> 1);
100         init(dir << 1 | 1 , ((l + r) >> 1) + 1 , r);
101         pushup(dir);
102     }
103 }
104
105 void change(int dir , int l , int r , int val){
106     if(Tree[dir].l >= l && Tree[dir].r <= r){
107         Tree[dir].lMax = Tree[dir].rMax = Tree[dir].midMax = max(Tree[dir].sum = (Tree[dir].mark = val) * (Tree[dir].r - Tree[dir].l + 1) , 0);
108         return;
109     }
110     pushdown(dir);
111     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
112         change(dir << 1 , l , r , val);
113     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
114         change(dir << 1 | 1 , l , r , val);
115     pushup(dir);
116 }
117
118 void askLeft(int dir , int l , int r){
119     if(Tree[dir].l >= l && Tree[dir].r <= r){
120         allMax = max(allMax , max(lMax + Tree[dir].rMax , Tree[dir].midMax));
121         lMax = max(Tree[dir].lMax , Tree[dir].sum + lMax);
122         return;
123     }
124     pushdown(dir);
125     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
126         askLeft(dir << 1 | 1 , l , r);
127     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
128         askLeft(dir << 1 , l , r);
129 }
130
131 void askRight(int dir , int l , int r){
132     if(Tree[dir].l >= l && Tree[dir].r <= r){
133         allMax = max(allMax , max(rMax + Tree[dir].rMax , Tree[dir].midMax));
134         rMax = max(Tree[dir].lMax , Tree[dir].sum + rMax);
135         return;
136     }
137     pushdown(dir);
138     if(r > (Tree[dir].l + Tree[dir].r) >> 1)
139         askRight(dir << 1 | 1 , l , r);
140     if(l <= (Tree[dir].l + Tree[dir].r) >> 1)
141         askRight(dir << 1 , l , r);
142 }
143
144 inline void work1(int l , int r , int val){
145     int tl = top[l] , tr = top[r];
146     while(tl != tr)
147         if(dep[tl] >= dep[tr]){
148             change(1 , ind[tl] , ind[l] , val);
149             tl = top[l = fa[tl]];
150         }
151         else{
152             change(1 , ind[tr] , ind[r] , val);
153             tr = top[r = fa[tr]];
154         }
155     if(ind[l] < ind[r])
156         change(1 , ind[l] , ind[r] , val);
157     else
158         change(1 , ind[r] , ind[l] , val);
159 }
160
161 inline void work2(int l , int r){
162     allMax = lMax = rMax = 0;
163     int tl = top[l] , tr = top[r];
164     while(tl != tr)
165         if(dep[tl] >= dep[tr]){
166             askLeft(1 , ind[tl] , ind[l]);
167             tl = top[l = fa[tl]];
168         }
169         else{
170             askRight(1 , ind[tr] , ind[r]);
171             tr = top[r = fa[tr]];
172         }
173     if(ind[l] < ind[r])
174         askRight(1 , ind[l] , ind[r]);
175     else
176         askLeft(1 , ind[r] , ind[l]);
177     print(max(allMax , lMax + rMax));
178 }
179
180 int main(){
181     N = read();
182     for(int i = 1 ; i <= N ; i++)
183         val[i] = read();
184     for(int i = 1 ; i < N ; i++){
185         int a = read() , b = read();
186         addEd(a , b);
187         addEd(b , a);
188     }
189     dfs1(1 , 0);
190     dfs2(1 , 1);
191     init(1 , 1 , N);
192     for(int Q = read() ; Q ; Q--){
193         int a = read() , b = read() , c = read();
194         if(a == 2)
195             work1(b , c , read());
196         else
197             work2(b , c);
198     }
199     return 0;
200 }

GSS7

转载于:https://www.cnblogs.com/Itst/p/9785592.html

SPOJ Can you answer the Queries系列相关推荐

  1. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  2. SPOJ GSS2 Can you answer these queries II (线段树离线) - xgtao -

    Can you answer these queries II 这是一道线段树的题目,维护历史版本,给出N(<=100000)个数字(-100000<=x<=100000),要求求出 ...

  3. 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国

    动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...

  4. HDU 4027 Can you answer these queries?(线段树/区间不等更新)

    传送门 Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/6576 ...

  5. HDU 1027 G - Can you answer these queries?

    http://acm.hdu.edu.cn/showproblem.php?pid=4027 Can you answer these queries? Time Limit: 4000/2000 M ...

  6. GSS2 - Can you answer these queries II

    GSS2 - Can you answer these queries II 题意: 给你1e51e51e5 的序列,每次询问区间l到rl到rl到r,每个相同的数只算一次的最大子段和. 思路: 乍一眼 ...

  7. Can you answer these queries I SPOJ - GSS1 (线段树维护区间连续最大值/最大连续子段和)...

    You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defi ...

  8. spoj 2916. Can you answer these queries V(线段树)

    题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出n个数,求区间最大子段和,但是限制了子段的起点终点,起点要在[x1,y1]内,终点要在[x2,y2]内. 思路 ...

  9. [SPOJ] 1043 Can you answer these queries I [GSS1]

    Pro 给你一个序列{A[1], A[2], ..., A[N]}.( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ) 给定"查询"操作的定义如下: Query( ...

最新文章

  1. 量子计算机科学原理,1000字看懂IBM量子计算机原理
  2. 【SQL】sql语句GROUP BY
  3. 第八章 工厂方法模式
  4. 算法设计与分析男女匹配问题C语言,C语言解决新郎和新娘配对问题代码解析
  5. 使用Nginx的proxy_cache缓存功能取代Squid[原创]
  6. 苹果cms的php.ini,苹果cms安装及配置详细教程
  7. sqlserver中查找长时间未提交事务
  8. iOS之深入解析dyld与ObjC关联的底层原理
  9. Timus1286(欧几里德算法的应用)
  10. 坑:找到LoadRunner中Recording Options和 Run Time Settings配置选项确实的原因
  11. 为何要搞 10 年?方舟编译器专家首次回应
  12. javajs ---- 判断字符串中是否包含子串
  13. eclipse 快捷键收藏
  14. 《恋上数据结构第1季》B树
  15. cplex java_【CPLEX教程03】java调用cplex求解一个TSP问题模型
  16. 世界各国国家代码简称
  17. 从亚马逊云科技“12字战略”,看企业数字化转型的“基座”与“底色”
  18. IOS 苹果手机 使用重力加速度,js web devicemotion,deviceorientation事件
  19. 视频编解码 — DCT变换和量化
  20. 超像素经典算法SLIC的代码的深度优化

热门文章

  1. python中如何导入数据包_如何在python中发送数据包?
  2. h5实现一键复制到粘贴板 兼容iOS
  3. 【动态规划笔记】01背包问题及优化
  4. MediaInfo源代码分析 1:整体结构
  5. ffdshow 源代码分析1 : 整体结构
  6. java word转pdf jacob_java使用jacob.jar将word转pdf
  7. Mac下IntelliJ IDEA常用快捷键
  8. Sitemesh3使用及配置
  9. linux下mysql 8.0配置大小写不敏感
  10. java 管道流_Java IO7:管道流、对象流