SPOJ Can you answer the Queries系列
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系列相关推荐
- SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并
Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...
- SPOJ GSS2 Can you answer these queries II (线段树离线) - xgtao -
Can you answer these queries II 这是一道线段树的题目,维护历史版本,给出N(<=100000)个数字(-100000<=x<=100000),要求求出 ...
- 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国
动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...
- HDU 4027 Can you answer these queries?(线段树/区间不等更新)
传送门 Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/6576 ...
- 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 ...
- GSS2 - Can you answer these queries II
GSS2 - Can you answer these queries II 题意: 给你1e51e51e5 的序列,每次询问区间l到rl到rl到r,每个相同的数只算一次的最大子段和. 思路: 乍一眼 ...
- 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 ...
- spoj 2916. Can you answer these queries V(线段树)
题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出n个数,求区间最大子段和,但是限制了子段的起点终点,起点要在[x1,y1]内,终点要在[x2,y2]内. 思路 ...
- [SPOJ] 1043 Can you answer these queries I [GSS1]
Pro 给你一个序列{A[1], A[2], ..., A[N]}.( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ) 给定"查询"操作的定义如下: Query( ...
最新文章
- 量子计算机科学原理,1000字看懂IBM量子计算机原理
- 【SQL】sql语句GROUP BY
- 第八章 工厂方法模式
- 算法设计与分析男女匹配问题C语言,C语言解决新郎和新娘配对问题代码解析
- 使用Nginx的proxy_cache缓存功能取代Squid[原创]
- 苹果cms的php.ini,苹果cms安装及配置详细教程
- sqlserver中查找长时间未提交事务
- iOS之深入解析dyld与ObjC关联的底层原理
- Timus1286(欧几里德算法的应用)
- 坑:找到LoadRunner中Recording Options和 Run Time Settings配置选项确实的原因
- 为何要搞 10 年?方舟编译器专家首次回应
- javajs ---- 判断字符串中是否包含子串
- eclipse 快捷键收藏
- 《恋上数据结构第1季》B树
- cplex java_【CPLEX教程03】java调用cplex求解一个TSP问题模型
- 世界各国国家代码简称
- 从亚马逊云科技“12字战略”,看企业数字化转型的“基座”与“底色”
- IOS 苹果手机 使用重力加速度,js web devicemotion,deviceorientation事件
- 视频编解码 — DCT变换和量化
- 超像素经典算法SLIC的代码的深度优化