SPOJ GSS(Can you answer the Queries)系列 4/8

GSS1(SPOJ又死了先贴个luogu的)

线段树最大子段和裸题,不带修改

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

注意pushup和getans就好

 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 }

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 }

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 }

GSS7

树剖+最大子段和

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

5.9K有史以来最长代码

  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 }

 

猜你喜欢

转载自www.cnblogs.com/Itst/p/9785592.html
今日推荐