SPOJ - QTREE4 Query on a tree IV 边分治

题目传送门

题意:有一棵数,每个节点有颜色,黑色或者白色,树边有边权,现在有2个操作,1修改某个点的颜色, 2询问2个白点的之前的路径权值最大和是多少。

题解:

边分治思路。

1.重构图。 因为边分治在菊花图的情况下情况不理想,所以需要先把图重新构建一下,是每个点的度数不超过3。

2.找在新图里面  一条边使得 断开这条边的情况下,左右2新树使得较大的那个子树是所有情况下的最小值。

3.开2个优先队列去维护左边新树的白点的最大值, 右边新树的所有白点的最大值, 然后 左边白点+右边白点+中间边就是最大值。

4.对于2个新图都执行 2-3的操作。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define lch(x) tr[x].son[0]
 12 #define rch(x) tr[x].son[1]
 13 #define max3(a,b,c) max(a,max(b,c))
 14 #define min3(a,b,c) min(a,min(b,c))
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 2e5 + 100;
 20 struct Node{
 21     int head[N]; int to[N<<1];
 22     int ct[N<<1]; int nt[N<<1];
 23     int tot;
 24     void init(){
 25         tot = 0;
 26         memset(head, -1, sizeof(head));
 27         return ;
 28     };
 29     void add(int u, int v, int val){
 30         to[tot] = v; ct[tot] = val;
 31         nt[tot] = head[u]; head[u] = tot++;
 32         return ;
 33     }
 34 }e[2];
 35 int n, u, v, w;
 36 void rebuild(int o, int u){
 37     int ff = 0;
 38     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
 39         v = e[0].to[i], w = e[0].ct[i];
 40         if(v == o) continue;
 41         if(!ff){
 42             e[1].add(u, v, w);
 43             e[1].add(v, u, w);
 44             ff = u;
 45         }
 46         else {
 47             ++n;
 48             e[1].add(ff, n, 0);
 49             e[1].add(n, ff, 0);
 50             e[1].add(v, n, w);
 51             e[1].add(n, v, w);
 52             ff = n;
 53         }
 54         rebuild(u, v);
 55     }
 56     return ;
 57 }
 58 vector<pll> vc[N];
 59 priority_queue<pll> pq[N<<2][2]; int wedge[N<<2];
 60 int white[N], sz[N];
 61 int cut[N<<1];
 62 int id, maxnum = 0;
 63 void get_edge(int o, int u, int num){
 64     sz[u] = 1;
 65     int tmp = 0;
 66     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 67         int v = e[1].to[i];
 68         if(v == o || cut[i>>1]) continue;
 69         get_edge(u, v, num);
 70         sz[u] += sz[v];
 71         tmp = max(num-sz[v], sz[v]);
 72         if(tmp < maxnum){
 73             id = i;
 74             maxnum = tmp;
 75         }
 76     }
 77     return ;
 78 }
 79 int k = 0, op;
 80 void dfs(int o, int u, int w){
 81     sz[u] = 1;
 82     if(white[u]){
 83         pq[k][op].push(pll(w, u));
 84         if(op == 0) vc[u].push_back(pll(-k, w));
 85         else vc[u].push_back(pll(k, w));
 86     }
 87     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 88         int v = e[1].to[i];
 89         if(v == o || cut[i>>1]) continue;
 90         dfs(u, v, w+e[1].ct[i]);
 91         sz[u] += sz[v];
 92     }
 93     return ;
 94 }
 95 int ans[N], lch[N], rch[N];
 96 void update(int k){
 97     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
 98     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
 99     if(pq[k][0].empty() || pq[k][1].empty())
100         ans[k] = 0;
101     else {
102         int val1 = pq[k][0].top().fi, val2 = pq[k][1].top().fi;
103         int sum = val1 + val2 + wedge[k];
104         ans[k] = max(sum, 0);
105     }
106     if(lch[k]) ans[k] = max(ans[k], ans[lch[k]]);
107     if(rch[k]) ans[k] = max(ans[k], ans[rch[k]]);
108     return ;
109 }
110 int solve(int u, int num){
111     if(num == 1) return 0;
112     maxnum = inf;
113     get_edge(0, u, num);
114     int now = ++k, nid = id;
115     cut[nid >> 1] = 1;
116     wedge[k] = e[1].ct[nid];
117     op = 0;
118     dfs(0, e[1].to[nid], 0);
119     op = 1;
120     dfs(0, e[1].to[nid^1], 0);
121     lch[now] = solve(e[1].to[nid], sz[e[1].to[nid]]);
122     rch[now] = solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
123     update(now);
124     return now;
125 }
126 void setWhite(int u){
127     for(int i = vc[u].size()-1; i >= 0; --i){
128         pll tmp = vc[u][i];
129         int k = tmp.fi, ct = tmp.se;
130         if(k < 0) pq[-k][0].push(pll(ct, u));
131         else pq[k][1].push(pll(ct, u));
132         update(abs(k));
133     }
134     return ;
135 }
136 void setBlack(int u){
137     for(int i = vc[u].size()-1; i >= 0; --i)
138         update(abs(vc[u][i].fi));
139     return ;
140 }
141 int main(){
142     scanf("%d", &n);
143     int white_num = n, q;
144     char op[10];
145     e[0].init(); e[1].init();
146     for(int i = 1; i < n; i++){
147         scanf("%d%d%d", &u, &v, &w);
148         e[0].add(u, v, w);
149         e[0].add(v, u, w);
150         white[i] = 1;
151     }
152     white[n] = 1;
153     rebuild(0, 1);
154     solve(1, n);
155     scanf("%d", &q);
156     while(q--){
157         scanf("%s", op);
158         if(op[0] == 'A') {
159             if(white_num == 0) puts("They have disappeared.");
160             else if(white_num == 1) puts("0");
161             else printf("%d\n", ans[1]);
162         }
163         else {
164             scanf("%d", &u);
165             white[u] ^= 1;
166             if(white[u])
167                 setWhite(u), ++white_num;
168             else
169                 setBlack(u), --white_num;
170         }
171     }
172     return 0;
173 }
View Code
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define lch(x) tr[x].son[0]
 12 #define rch(x) tr[x].son[1]
 13 #define max3(a,b,c) max(a,max(b,c))
 14 #define min3(a,b,c) min(a,min(b,c))
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 2e5 + 100;
 20 struct Node{
 21     int head[N]; int to[N<<1];
 22     int ct[N<<1]; int nt[N<<1];
 23     int tot;
 24     void init(){
 25         tot = 0;
 26         memset(head, -1, sizeof(head));
 27         return ;
 28     };
 29     void add(int u, int v, int val){
 30         to[tot] = v; ct[tot] = val;
 31         nt[tot] = head[u]; head[u] = tot++;
 32         return ;
 33     }
 34 }e[2];
 35 int n, u, v, w;
 36 void rebuild(int o, int u){
 37     int ff = 0;
 38     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
 39         v = e[0].to[i], w = e[0].ct[i];
 40         if(v == o) continue;
 41         if(!ff){
 42             e[1].add(u, v, w);
 43             e[1].add(v, u, w);
 44             ff = u;
 45         }
 46         else {
 47             ++n;
 48             e[1].add(ff, n, 0);
 49             e[1].add(n, ff, 0);
 50             e[1].add(v, n, w);
 51             e[1].add(n, v, w);
 52             ff = n;
 53         }
 54         rebuild(u, v);
 55     }
 56     return ;
 57 }
 58 vector<pll> vc[N];
 59 priority_queue<pll> pq[N<<2][2]; int wedge[N<<2];
 60 int white[N], sz[N];
 61 int cut[N<<1];
 62 int id, maxnum = 0;
 63 void get_edge(int o, int u, int num){
 64     sz[u] = 1;
 65     int tmp = 0;
 66     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 67         int v = e[1].to[i];
 68         if(v == o || cut[i>>1]) continue;
 69         get_edge(u, v, num);
 70         sz[u] += sz[v];
 71         tmp = max(num-sz[v], sz[v]);
 72         if(tmp < maxnum){
 73             id = i;
 74             maxnum = tmp;
 75         }
 76     }
 77     return ;
 78 }
 79 int k = 0, op;
 80 void dfs(int o, int u, int w){
 81     sz[u] = 1;
 82     if(white[u]){
 83         pq[k][op].push(pll(w, u));
 84         if(op == 0) vc[u].push_back(pll(-k, w));
 85         else vc[u].push_back(pll(k, w));
 86     }
 87     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 88         int v = e[1].to[i];
 89         if(v == o || cut[i>>1]) continue;
 90         dfs(u, v, w+e[1].ct[i]);
 91         sz[u] += sz[v];
 92     }
 93     return ;
 94 }
 95 int ans[N], lch[N], rch[N];
 96 void update(int k){
 97     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
 98     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
 99     if(pq[k][0].empty() || pq[k][1].empty())
100         ans[k] = 0;
101     else {
102         int val1 = pq[k][0].top().fi, val2 = pq[k][1].top().fi;
103         int sum = val1 + val2 + wedge[k];
104         ans[k] = max(sum, 0);
105     }
106     if(lch[k]) ans[k] = max(ans[k], ans[lch[k]]);
107     if(rch[k]) ans[k] = max(ans[k], ans[rch[k]]);
108     return ;
109 }
110 int solve(int u, int num){
111     if(num == 1) return 0;
112     maxnum = inf;
113     get_edge(0, u, num);
114     int now = ++k, nid = id;
115     cut[nid >> 1] = 1;
116     wedge[k] = e[1].ct[nid];
117     op = 0;
118     dfs(0, e[1].to[nid], 0);
119     op = 1;
120     dfs(0, e[1].to[nid^1], 0);
121     lch[now] = solve(e[1].to[nid], sz[e[1].to[nid]]);
122     rch[now] = solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
123     update(now);
124     return now;
125 }
126 void setWhite(int u){
127     for(int i = vc[u].size()-1; i >= 0; --i){
128         pll tmp = vc[u][i];
129         int k = tmp.fi, ct = tmp.se;
130         if(k < 0) pq[-k][0].push(pll(ct, u));
131         else pq[k][1].push(pll(ct, u));
132         update(abs(k));
133     }
134     return ;
135 }
136 void setBlack(int u){
137     for(int i = vc[u].size()-1; i >= 0; --i)
138         update(abs(vc[u][i].fi));
139     return ;
140 }
141 int main(){
142     scanf("%d", &n);
143     int white_num = n, q;
144     char op[10];
145     e[0].init(); e[1].init();
146     for(int i = 1; i < n; i++){
147         scanf("%d%d%d", &u, &v, &w);
148         e[0].add(u, v, w);
149         e[0].add(v, u, w);
150         white[i] = 1;
151     }
152     white[n] = 1;
153     rebuild(0, 1);
154     solve(1, n);
155     scanf("%d", &q);
156     while(q--){
157         scanf("%s", op);
158         if(op[0] == 'A') {
159             if(white_num == 0) puts("They have disappeared.");
160             else if(white_num == 1) puts("0");
161             else printf("%d\n", ans[1]);
162         }
163         else {
164             scanf("%d", &u);
165             white[u] ^= 1;
166             if(white[u])
167                 setWhite(u), ++white_num;
168             else
169                 setBlack(u), --white_num;
170         }
171     }
172     return 0;
173 }
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9879463.html