标签:
这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节。。
点分治:
主要就是3个堆的初始状态
C堆:每个节点一个,为子树中的点到它父亲的距离的堆。
B堆:每个节点一个,存所有儿子的堆的堆顶。特别地,如果该节点关灯,那么将加入一个0;如果没有元素,堆顶应返回负数。
A堆:全局一个,存所有B堆的最大值和最小值之和。特别地,如果B堆不足两个,返回负数。
这样,我们一开始需要关闭所有的等,即对所有点调用一次turn_off。由于堆顶返回的是负数,删除时找不到的话直接忽略即可,如果返回的是0,则有可能误删有用的信息。
代码:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 100000 + 10, logn = 17; 6 7 struct RMQ { 8 int n, f[logn + 1][N * 2], Log[N * 2]; 9 void init(int n) { 10 Log[0] = -1; 11 for(int i = 1; i <= n; i++) Log[i] = Log[i >> 1] + 1; 12 this->n = n; 13 for(int i = 1; (1 << i) < n; i++) { 14 for(int j = 1; j <= n; j++) { 15 f[i][j] = min(f[i-1][j], f[i-1][j + (1 << (i-1))]); 16 } 17 } 18 } 19 20 int query(int l, int r) { 21 int t = Log[r - l + 1]; 22 return min(f[t][l], f[t][r - (1 << t) + 1]); 23 } 24 } rmq; 25 26 struct Edge { 27 int to; Edge *next; 28 } pool[N * 2], *pis = pool, *fir[N]; 29 30 void AddEdge(int u, int v) { 31 pis->to = v, pis->next = fir[u], fir[u] = pis++; 32 } 33 34 int dfn[N], dfs_clock, *seq = rmq.f[0], dep[N], ds[N], tot; 35 36 #define v p->to 37 void dfs(int u, int fa) { 38 dfn[u] = ++dfs_clock; 39 seq[dfs_clock] = dep[u]; 40 for(Edge *p = fir[u]; p; p = p->next) { 41 if(v != fa) { 42 dep[v] = dep[u] + 1, dfs(v, u); 43 seq[++dfs_clock] = dep[u]; 44 } 45 } 46 ds[tot++] = u; 47 } 48 #undef v 49 50 int dis(int u, int v) { 51 if(dfn[u] > dfn[v]) swap(u, v); 52 return dep[u] + dep[v] - (rmq.query(dfn[u], dfn[v]) << 1); 53 } 54 const int INF = 1 << 29; 55 56 struct Set { 57 multiset<int> s; 58 void insert(int x) {s.insert(x);} 59 void erase(int x) { 60 multiset<int>::iterator it = s.find(x); 61 if(it != s.end()) s.erase(it); 62 } 63 int size() const {return s.size();} 64 int top() {return s.empty() ? -INF : *--s.end();} 65 int query() { 66 if(s.size() < 2) return -INF; 67 return *--s.end() + *----s.end(); 68 } 69 } A, B[N], C[N]; 70 71 void print(const Set &ss) { 72 const multiset<int> &s = ss.s; 73 for(multiset<int>::iterator it = s.begin(); it != s.end(); ++it) { 74 printf("%d ", *it); 75 } 76 puts(""); 77 } 78 bool centre[N]; 79 int fa[N], maxsz[N], sz[N], root; 80 81 #define v p->to 82 void dfs_size(int u, int fa) { 83 sz[u] = 1, maxsz[u] = 0; 84 for(Edge *p = fir[u]; p; p = p->next) { 85 if(!centre[v] && v != fa) { 86 dfs_size(v, u); 87 sz[u] += sz[v]; 88 maxsz[u] = max(maxsz[u], sz[v]); 89 } 90 } 91 } 92 93 void dfs_root(int u, int fa, int r) { 94 maxsz[u] = max(maxsz[u], sz[r] - sz[u]); 95 if(maxsz[u] < maxsz[root]) root = u; 96 for(Edge *p = fir[u]; p; p = p->next) { 97 if(!centre[v] && v != fa) dfs_root(v, u, r); 98 } 99 } 100 101 void divide(int u, int _fa) { 102 dfs_size(u, 0), dfs_root(u, 0, root = u); 103 centre[u = root] = 1, fa[u] = _fa; 104 for(Edge *p = fir[u]; p; p = p->next) { 105 if(!centre[v]) divide(v, u); 106 } 107 } 108 #undef v 109 110 void add(int u, int v, int flag) { 111 if(u == v) { 112 A.erase(B[u].query()); 113 if(flag) B[u].insert(0); 114 else B[u].erase(0); 115 A.insert(B[u].query()); 116 } 117 int f = fa[u]; 118 if(!f) return; 119 A.erase(B[f].query()); 120 B[f].erase(C[u].top()); 121 if(flag) C[u].insert(dis(f, v)); 122 else C[u].erase(dis(f, v)); 123 B[f].insert(C[u].top()); 124 A.insert(B[f].query()); 125 add(f, v, flag); 126 } 127 128 int col[N]; 129 130 int main() { 131 #ifdef DEBUG 132 freopen("in.txt", "r", stdin); 133 #endif 134 135 int n; scanf("%d", &n); 136 for(int i = 1; i < n; i++) { 137 int u, v; scanf("%d%d", &u, &v); 138 AddEdge(u, v), AddEdge(v, u); 139 } 140 dfs(1, 0); 141 rmq.init((n << 1) - 1); 142 divide(1, 0); 143 int cnt_off = n; 144 for(int i = 0; i < n; i++) 145 add(ds[i], ds[i], col[ds[i]] = 1); 146 147 int m, u; scanf("%d", &m); 148 char opt[8]; 149 while(m--) { 150 scanf("%s", opt); 151 if(opt[0] == ‘G‘) { 152 if(cnt_off == 0) puts("-1"); 153 else if(cnt_off == 1) puts("0"); 154 else printf("%d\n", A.top()); 155 } else { 156 scanf("%d", &u), add(u, u, col[u] ^= 1); 157 if(col[u]) cnt_off++; else cnt_off--; 158 } 159 } 160 161 return 0; 162 }
标签:
原文地址:http://www.cnblogs.com/showson/p/5578611.html