标签:
寒假后半段一直都在外出旅游。。颓了好久。。qaq
旅游期间写了几道树剖模板题,贴上来。。
BZOJ 1036 没啥好说的,裸题
1 #include <cstdio> 2 #include <algorithm> 3 4 #define LEFT (segt[cur].l) 5 #define RIGHT (segt[cur].r) 6 #define MID (segt[cur].mid) 7 #define SUM (segt[cur].Sum) 8 #define MAX (segt[cur].Max) 9 #define LCH (cur << 1) 10 #define RCH ((cur << 1) | 1) 11 12 using namespace std; 13 14 void Get_Val(int &Ret) 15 { 16 Ret = 0; 17 char ch; 18 bool neg(false); 19 while (ch = getchar(), (ch > ‘9‘ || ch < ‘0‘) && ch != ‘-‘) 20 ; 21 if (ch == ‘-‘) 22 { 23 neg = true; 24 while (ch = getchar(), ch > ‘9‘ || ch < ‘0‘) 25 ; 26 } 27 do 28 { 29 (Ret *= 10) += ch - ‘0‘; 30 } 31 while (ch = getchar(), ch >= ‘0‘ && ch <= ‘9‘); 32 Ret = (neg ? -Ret : Ret); 33 } 34 35 const int Max_N(30050); 36 const int root(1); 37 38 int N; 39 int W[Max_N]; 40 int Total, Head[Max_N], To[Max_N << 1], Next[Max_N << 1]; 41 int Father[Max_N], Deep[Max_N], Size[Max_N], Son[Max_N], Top[Max_N], ID[Max_N]; 42 int Tot, Number[Max_N]; 43 44 struct node 45 { 46 int l, r, mid; 47 int Sum, Max; 48 }; 49 50 struct Segment_Tree 51 { 52 node segt[Max_N << 2]; 53 void Make_Tree(const int&, const int&, const int&); 54 inline 55 void pushup(const int &cur) 56 { 57 MAX = max(segt[LCH].Max, segt[RCH].Max); 58 SUM = segt[LCH].Sum + segt[RCH].Sum; 59 } 60 void Change(const int&, const int&, const int&); 61 int RMQ_Max(const int&, const int&, const int&); 62 int Query_Sum(const int&, const int&, const int&); 63 }; 64 Segment_Tree Tree; 65 66 void Segment_Tree::Make_Tree(const int &cur, const int &l, const int &r) 67 { 68 LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), SUM = 0, MAX = 0; 69 if (l == r) 70 { 71 SUM = MAX = W[ID[l]]; 72 return; 73 } 74 Make_Tree(LCH, l, MID); 75 Make_Tree(RCH, MID + 1, r); 76 pushup(cur); 77 } 78 79 void Segment_Tree::Change(const int &cur, const int &i, const int &x) 80 { 81 if (LEFT == i && RIGHT == i) 82 { 83 SUM = MAX = x; 84 return; 85 } 86 if (i <= MID) 87 Change(LCH, i, x); 88 else 89 Change(RCH, i, x); 90 pushup(cur); 91 } 92 93 int Segment_Tree::RMQ_Max(const int &cur, const int &l, const int &r) 94 { 95 if (l == LEFT && r == RIGHT) 96 return MAX; 97 if (r <= MID) 98 return RMQ_Max(LCH, l, r); 99 else 100 if (l > MID) 101 return RMQ_Max(RCH, l, r); 102 else 103 return max(RMQ_Max(LCH, l, MID), RMQ_Max(RCH, MID + 1, r)); 104 } 105 106 int Segment_Tree::Query_Sum(const int &cur, const int &l, const int &r) 107 { 108 if (l == LEFT && r == RIGHT) 109 return SUM; 110 if (r <= MID) 111 return Query_Sum(LCH, l, r); 112 else 113 if (l > MID) 114 return Query_Sum(RCH, l, r); 115 else 116 return Query_Sum(LCH, l, MID) + Query_Sum(RCH, MID + 1, r); 117 } 118 119 inline 120 void Add_Edge(const int &s, const int &t) 121 { 122 ++Total; 123 To[Total] = t; 124 Next[Total] = Head[s], Head[s] = Total; 125 } 126 127 void dfs1(const int &u, const int &fa) 128 { 129 Size[u] = 1; 130 int v; 131 for (int i = Head[u];i;i = Next[i]) 132 { 133 v = To[i]; 134 if (v != fa) 135 { 136 Father[v] = u, Deep[v] = Deep[u] + 1; 137 dfs1(v, u); 138 Size[u] += Size[v]; 139 if (Size[v] > Size[Son[u]]) 140 Son[u] = v; 141 } 142 } 143 } 144 145 void dfs2(const int &u, const int &fa) 146 { 147 Number[u] = ++Tot, ID[Tot] = u; 148 int v; 149 if (v = Son[u]) 150 { 151 Top[v] = Top[u]; 152 dfs2(v, u); 153 } 154 for (int i = Head[u];i;i = Next[i]) 155 { 156 v = To[i]; 157 if (v != fa && v != Son[u]) 158 { 159 Top[v] = v; 160 dfs2(v, u); 161 } 162 } 163 } 164 165 void init() 166 { 167 int a, b; 168 Get_Val(N); 169 for (int i = 1;i != N;++i) 170 { 171 Get_Val(a), Get_Val(b); 172 Add_Edge(a, b), Add_Edge(b, a); 173 } 174 for (int i = 1;i <= N;++i) 175 Get_Val(W[i]); 176 Deep[root] = 1, dfs1(root, Father[root] = -1); 177 Top[root] = root, dfs2(root, -1); 178 } 179 180 int Query_Max(int u, int v) 181 { 182 int Max(-0X7F7F7F7F); 183 int r1(Top[u]), r2(Top[v]); 184 while (r1 != r2) 185 { 186 if (Deep[r1] < Deep[r2]) 187 swap(u, v), swap(r1, r2); 188 Max = max(Max, Tree.RMQ_Max(1, Number[r1], Number[u])); 189 u = Father[r1]; 190 r1 = Top[u]; 191 } 192 if (Deep[u] > Deep[v]) 193 swap(u, v); 194 return max(Max, Tree.RMQ_Max(1, Number[u], Number[v])); 195 } 196 197 int Query_Sum(int u, int v) 198 { 199 int Sum(0); 200 int r1(Top[u]), r2(Top[v]); 201 while (r1 != r2) 202 { 203 if (Deep[r1] < Deep[r2]) 204 swap(u, v), swap(r1, r2); 205 Sum += Tree.Query_Sum(1, Number[r1], Number[u]); 206 u = Father[r1]; 207 r1 = Top[u]; 208 } 209 if (Deep[u] > Deep[v]) 210 swap(u, v); 211 return Sum + Tree.Query_Sum(1, Number[u], Number[v]); 212 } 213 214 void work() 215 { 216 Tree.Make_Tree(1, 1, N); 217 int Q, u, v; 218 char op[10]; 219 Get_Val(Q); 220 while (Q--) 221 { 222 scanf("%s", op), Get_Val(u), Get_Val(v); 223 if (*op == ‘C‘) 224 Tree.Change(1, Number[u], v); 225 else 226 if (op[1] == ‘M‘) 227 printf("%d\n", Query_Max(u, v)); 228 else 229 printf("%d\n", Query_Sum(u, v)); 230 } 231 } 232 233 int main() 234 { 235 init(); 236 work(); 237 return 0; 238 }
BZOJ 2157 边权转点权。。点权表示的是这个点到它父亲的边的权值,根节点的点权设置为无意义的值,比如和是0,最大值是-INF,最小值是INF。树剖修改查询的时候,只需要最后一步提升时,将两个点的lca无视即可。具体看代码。。写了7kbqaq
1 #include <cstdio> 2 #include <algorithm> 3 #define LEFT (segt[cur].l) 4 #define RIGHT (segt[cur].r) 5 #define MID (segt[cur].mid) 6 #define SUM (segt[cur].Sum) 7 #define MAX (segt[cur].Max) 8 #define MIN (segt[cur].Min) 9 #define TAG (segt[cur].Tag) 10 #define LCH (cur << 1) 11 #define RCH ((cur << 1) | 1) 12 13 using namespace std; 14 15 void Get_Val(int &Ret) 16 { 17 Ret = 0; 18 char ch; 19 bool neg(false); 20 while (ch = getchar(), (ch > ‘9‘ || ch < ‘0‘) && ch != ‘-‘) 21 ; 22 if (ch == ‘-‘) 23 { 24 neg = true; 25 while (ch = getchar(), ch > ‘9‘ || ch < ‘0‘) 26 ; 27 } 28 do 29 { 30 (Ret *= 10) += ch -‘0‘; 31 } 32 while (ch = getchar(), ch >= ‘0‘ && ch <= ‘9‘); 33 if (neg) 34 Ret = -Ret; 35 } 36 37 const int Max_N(20050); 38 const int root(1); 39 const int INF(0X3F3F3F3F); 40 41 struct edge 42 { 43 int u, v; 44 }; 45 edge Edges[Max_N]; 46 47 int N; 48 int Total, Head[Max_N], To[Max_N << 1], Next[Max_N << 1], Weight[Max_N << 1]; 49 int Father[Max_N], Cost[Max_N], Deep[Max_N], Size[Max_N], Son[Max_N], Top[Max_N]; 50 int Dfs_Clock, Pre[Max_N], ID[Max_N]; 51 52 inline 53 void Add_Edge(const int &s, const int &t, const int &w) 54 { 55 ++Total; 56 To[Total] = t, Weight[Total] = w; 57 Next[Total] = Head[s], Head[s] = Total; 58 } 59 60 struct node 61 { 62 int l, r, mid; 63 int Sum, Max, Min; 64 bool Tag; 65 }; 66 67 struct Segment_Tree 68 { 69 node segt[Max_N << 2]; 70 void build_tree(const int&, const int&, const int&); 71 inline 72 void pushup(const int &cur) 73 { 74 SUM = segt[LCH].Sum + segt[RCH].Sum; 75 MAX = max(segt[LCH].Max, segt[RCH].Max), MIN = min(segt[LCH].Min, segt[RCH].Min); 76 } 77 inline 78 void pushdown(const int &cur) 79 { 80 if (TAG) 81 { 82 segt[LCH].Sum = -segt[LCH].Sum; 83 segt[RCH].Sum = -segt[RCH].Sum; 84 swap((segt[LCH].Max = -segt[LCH].Max), (segt[LCH].Min = -segt[LCH].Min)); 85 swap((segt[RCH].Max = -segt[RCH].Max), (segt[RCH].Min = -segt[RCH].Min)); 86 segt[LCH].Tag = !segt[LCH].Tag, segt[RCH].Tag = !segt[RCH].Tag; 87 TAG = false; 88 } 89 } 90 void change(const int&, const int&, const int&); 91 void opposite(const int&, const int&, const int&); 92 int Sum(const int&, const int&, const int&); 93 int Min(const int&, const int&, const int&); 94 int Max(const int&, const int&, const int&); 95 }; 96 Segment_Tree Tree; 97 98 void Segment_Tree::build_tree(const int &cur, const int &l, const int &r) 99 { 100 LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), TAG = false; 101 if (l == r) 102 { 103 if (ID[l] == root) 104 MAX = -INF, MIN = INF, SUM = 0; 105 else 106 MAX = MIN = SUM = Cost[ID[l]]; 107 return; 108 } 109 build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r); 110 pushup(cur); 111 } 112 113 void Segment_Tree::change(const int &cur, const int &i, const int &x) 114 { 115 if (LEFT == i && RIGHT == i) 116 { 117 SUM = MAX = MIN = x; 118 return; 119 } 120 pushdown(cur); 121 if (i <= MID) 122 change(LCH, i, x); 123 else 124 change(RCH, i, x); 125 pushup(cur); 126 } 127 128 void Segment_Tree::opposite(const int &cur, const int &l, const int &r) 129 { 130 if (LEFT == l && RIGHT == r) 131 { 132 SUM = -SUM; 133 swap((MAX = -MAX), (MIN = -MIN)); 134 TAG = !TAG; 135 return; 136 } 137 pushdown(cur); 138 if (r <= MID) 139 opposite(LCH, l, r); 140 else 141 if (l > MID) 142 opposite(RCH, l, r); 143 else 144 { 145 opposite(LCH, l, MID); 146 opposite(RCH, MID + 1, r); 147 } 148 pushup(cur); 149 } 150 151 int Segment_Tree::Sum(const int &cur, const int &l, const int &r) 152 { 153 if (LEFT == l && RIGHT == r) 154 return SUM; 155 pushdown(cur); 156 if (r <= MID) 157 return Sum(LCH, l, r); 158 else 159 if (l > MID) 160 return Sum(RCH, l, r); 161 else 162 return Sum(LCH, l, MID) + Sum(RCH, MID + 1, r); 163 } 164 165 int Segment_Tree::Max(const int &cur, const int &l, const int &r) 166 { 167 if (LEFT == l && RIGHT == r) 168 return MAX; 169 pushdown(cur); 170 if (r <= MID) 171 return Max(LCH, l, r); 172 else 173 if (l > MID) 174 return Max(RCH, l, r); 175 else 176 return max(Max(LCH, l, MID), Max(RCH, MID + 1, r)); 177 } 178 179 int Segment_Tree::Min(const int &cur, const int &l, const int &r) 180 { 181 if (LEFT == l && RIGHT == r) 182 return MIN; 183 pushdown(cur); 184 if (r <= MID) 185 return Min(LCH, l, r); 186 else 187 if (l > MID) 188 return Min(RCH, l, r); 189 else 190 return min(Min(LCH, l, MID), Min(RCH, MID + 1, r)); 191 } 192 193 void Opposite(int u, int v) 194 { 195 int r1(Top[u]), r2(Top[v]); 196 while (r1 != r2) 197 { 198 if (Deep[r1] < Deep[r2]) 199 swap(u, v), swap(r1, r2); 200 Tree.opposite(1, Pre[r1], Pre[u]); 201 u = Father[r1], r1 = Top[u]; 202 } 203 if (Deep[u] > Deep[v]) 204 swap(u, v); 205 if (Pre[u] + 1 <= Pre[v]) 206 Tree.opposite(1, Pre[u] + 1, Pre[v]); 207 } 208 209 int Query_Sum(int u, int v) 210 { 211 int Ans(0), r1(Top[u]), r2(Top[v]); 212 while (r1 != r2) 213 { 214 if (Deep[r1] < Deep[r2]) 215 swap(u, v), swap(r1, r2); 216 Ans += Tree.Sum(1, Pre[r1], Pre[u]); 217 u = Father[r1], r1 = Top[u]; 218 } 219 if (Deep[u] > Deep[v]) 220 swap(u, v); 221 if (Pre[u] + 1 <= Pre[v]) 222 Ans += Tree.Sum(1, Pre[u] + 1, Pre[v]); 223 return Ans; 224 } 225 226 int Query_Max(int u, int v) 227 { 228 int Ans(-INF), r1(Top[u]), r2(Top[v]); 229 while (r1 != r2) 230 { 231 if (Deep[r1] < Deep[r2]) 232 swap(u, v), swap(r1, r2); 233 Ans = max(Ans, Tree.Max(1, Pre[r1], Pre[u])); 234 u = Father[r1], r1 = Top[u]; 235 } 236 if (Deep[u] > Deep[v]) 237 swap(u, v); 238 if (Pre[u] + 1 <= Pre[v]) 239 Ans = max(Ans, Tree.Max(1, Pre[u] + 1, Pre[v])); 240 return Ans; 241 } 242 243 int Query_Min(int u, int v) 244 { 245 int Ans(INF), r1(Top[u]), r2(Top[v]); 246 while (r1 != r2) 247 { 248 if (Deep[r1] < Deep[r2]) 249 swap(u, v), swap(r1, r2); 250 Ans = min(Ans, Tree.Min(1, Pre[r1], Pre[u])); 251 u = Father[r1], r1 = Top[u]; 252 } 253 if (Deep[u] > Deep[v]) 254 swap(u, v); 255 if (Pre[u] + 1 <= Pre[v]) 256 Ans = min(Ans, Tree.Min(1, Pre[u] + 1, Pre[v])); 257 return Ans; 258 } 259 260 void dfs1(const int &u, const int &fa) 261 { 262 int v; 263 Size[u] = 1; 264 for (int i = Head[u];i;i = Next[i]) 265 { 266 v = To[i]; 267 if (v != fa) 268 { 269 Father[v] = u, Deep[v] = Deep[u] + 1, Cost[v] = Weight[i]; 270 dfs1(v, u); 271 Size[u] += Size[v]; 272 if (Size[v] > Size[Son[u]]) 273 Son[u] = v; 274 } 275 } 276 } 277 278 void dfs2(const int &u) 279 { 280 Pre[u] = ++Dfs_Clock, ID[Dfs_Clock] = u; 281 int v; 282 if (v = Son[u]) 283 { 284 Top[v] = Top[u]; 285 dfs2(v); 286 } 287 for (int i = Head[u];i;i = Next[i]) 288 { 289 v = To[i]; 290 if (v != Father[u] && v != Son[u]) 291 { 292 Top[v] = v; 293 dfs2(v); 294 } 295 } 296 } 297 298 void init() 299 { 300 int u, v, w; 301 Get_Val(N); 302 for (int i = 1;i != N;++i) 303 { 304 Get_Val(u), Get_Val(v), Get_Val(w), ++u, ++v; 305 Add_Edge(u, v, w), Add_Edge(v, u, w); 306 Edges[i].u = u, Edges[i].v = v; 307 } 308 Deep[root] = 1, dfs1(root, Father[root] = -1); 309 Top[root] = root, dfs2(root); 310 } 311 312 void work() 313 { 314 int M, u, v; 315 char op[10]; 316 Tree.build_tree(1, 1, N); 317 Get_Val(M); 318 while (M--) 319 { 320 scanf("%s", op), Get_Val(u), Get_Val(v); 321 if (*op == ‘C‘) 322 { 323 if (Deep[Edges[u].u] < Deep[Edges[u].v]) 324 u = Edges[u].v; 325 else 326 u = Edges[u].u; 327 Tree.change(1, Pre[u], v); 328 } 329 else 330 if (*op == ‘N‘) 331 ++u, ++v, Opposite(u, v); 332 else 333 if (*op == ‘S‘) 334 ++u, ++v, printf("%d\n", Query_Sum(u, v)); 335 else 336 if (op[1] == ‘A‘) 337 ++u, ++v, printf("%d\n", Query_Max(u, v)); 338 else 339 ++u, ++v, printf("%d\n", Query_Min(u, v)); 340 } 341 } 342 343 int main() 344 { 345 init(); 346 work(); 347 return 0; 348 }
BZOJ 2243 树剖+线段树区间合并,合并区间的时候还要判断左区间的右端点和右区间的左端点是否相同
#include <cstdio> #include <algorithm> #define LEFT (segt[cur].l) #define RIGHT (segt[cur].r) #define MID (segt[cur].mid) #define PIECE (segt[cur].piece) #define LC (segt[cur].lc) #define RC (segt[cur].rc) #define TAG (segt[cur].Tag) #define LCH (cur << 1) #define RCH ((cur << 1) | 1) using namespace std; void Get_Val(int &Ret) { Ret = 0; char ch; while (ch = getchar(), ch > ‘9‘ || ch < ‘0‘) ; do { (Ret *= 10) += ch - ‘0‘; } while (ch = getchar(), ch >= ‘0‘ && ch <= ‘9‘); } const int Max_N(100050); const int root(1); int N, M; int Colour[Max_N]; int Total, Head[Max_N], To[Max_N << 1], Next[Max_N << 1]; int Father[Max_N], Deep[Max_N], Size[Max_N], Son[Max_N], Top[Max_N]; int Tot, Pre[Max_N], ID[Max_N]; struct question { question(const int &a = 0, const int &b = 0, const int &c = 0) : piece(a), lc(b), rc(c) {} int piece, lc, rc; }; struct node { int l, r, mid; int piece; int lc, rc; int Tag; }; struct Segment_Tree { node segt[Max_N << 2]; void build_tree(const int&, const int&, const int&); inline void pushup(const int &cur) { PIECE = segt[LCH].piece + segt[RCH].piece - (segt[LCH].rc == segt[RCH].lc); LC = segt[LCH].lc, RC = segt[RCH].rc; } inline void pushdown(const int &cur) { if (TAG != -1) { segt[LCH].piece = segt[RCH].piece = 1; segt[LCH].lc = segt[LCH].rc = segt[RCH].lc = segt[RCH].rc = TAG; segt[LCH].Tag = segt[RCH].Tag = TAG; TAG = -1; } } void Set(const int&, const int&, const int&, const int&); question Query(const int&, const int&, const int&); }; Segment_Tree Tree; void Segment_Tree::build_tree(const int &cur, const int &l, const int &r) { LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), TAG = -1; if (l == r) { PIECE = 1; LC = RC = Colour[ID[l]]; return; } build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r); pushup(cur); } void Segment_Tree::Set(const int &cur, const int &l, const int &r, const int &col) { if (l == LEFT && r == RIGHT) { PIECE = 1; LC = RC = TAG = col; return; } pushdown(cur); if (r <= MID) Set(LCH, l, r, col); else if (l > MID) Set(RCH, l, r, col); else { Set(LCH, l, MID, col); Set(RCH, MID + 1, r, col); } pushup(cur); } question Segment_Tree::Query(const int &cur, const int &l, const int &r) { if (l == LEFT && r == RIGHT) return question(PIECE, LC, RC); pushdown(cur); if (r <= MID) return Query(LCH, l, r); else if (l > MID) return Query(RCH, l, r); else { question ltree, rtree; ltree = Query(LCH, l, MID), rtree = Query(RCH, MID + 1, r); return question(ltree.piece + rtree.piece - (ltree.rc == rtree.lc), ltree.lc, rtree.rc); } } inline void Add_Edge(const int &s, const int &t) { ++Total; To[Total] = t; Next[Total] = Head[s], Head[s] = Total; } void dfs1(const int &u, const int &fa) { Size[u] = 1; int v; for (int i = Head[u];i;i = Next[i]) { v = To[i]; if (v != fa) { Father[v] = u, Deep[v] = Deep[u] + 1; dfs1(v, u); Size[u] += Size[v]; if (Size[v] > Size[Son[u]]) Son[u] = v; } } } void dfs2(const int &u) { int v; Pre[u] = ++Tot, ID[Tot] = u; if (v = Son[u]) { Top[v] = Top[u]; dfs2(v); } for (int i = Head[u];i;i = Next[i]) { v = To[i]; if (v != Father[u] && v != Son[u]) { Top[v] = v; dfs2(v); } } } void change(int u, int v, const int &c) { int r1(Top[u]), r2(Top[v]); while (r1 != r2) { if (Deep[r1] < Deep[r2]) swap(u, v), swap(r1, r2); Tree.Set(1, Pre[r1], Pre[u], c); u = Father[r1], r1 = Top[u]; } if (Deep[u] > Deep[v]) swap(u, v); Tree.Set(1, Pre[u], Pre[v], c); } int query(int u, int v) { int last_u_l(-1), last_u_r(-1), last_v_l(-1), last_v_r(-1); int now_u_l, now_u_r; int r1(Top[u]), r2(Top[v]), Ans(0); question now; while (r1 != r2) { if (Deep[r1] < Deep[r2]) swap(u, v), swap(r1, r2), swap(last_u_l, last_v_l), swap(last_u_r, last_v_r); now = Tree.Query(1, Pre[r1], Pre[u]); Ans += now.piece, now_u_l = now.lc, now_u_r = now.rc; Ans -= (now_u_r == last_u_l); last_u_l = now_u_l, last_u_r = now_u_r; u = Father[r1], r1 = Top[u]; } if (Deep[u] > Deep[v]) swap(u, v), swap(last_u_l, last_v_l), swap(last_u_r, last_v_r); now = Tree.Query(1, Pre[u], Pre[v]); Ans += now.piece, now_u_l = now.lc, now_u_r = now.rc; Ans -= (now_u_l == last_u_l) + (now_u_r == last_v_l); return Ans; } void init() { int x, y; Get_Val(N), Get_Val(M); for (int i = 1;i <= N;++i) Get_Val(Colour[i]); for (int i = 1;i != N;++i) { Get_Val(x), Get_Val(y); Add_Edge(x, y), Add_Edge(y, x); } Deep[root] = 1, dfs1(root, Father[root] = -1); Top[root] = root, dfs2(root); } void work() { char op[5]; int a, b, c; Tree.build_tree(1, 1, N); while (M--) { scanf("%s", op); if (*op == ‘C‘) { Get_Val(a), Get_Val(b), Get_Val(c); change(a, b, c); } else { Get_Val(a), Get_Val(b); printf("%d\n", query(a, b)); } } } int main() { init(); work(); return 0; }
BZOJ 4034 不说了,裸题
1 #include <cstdio> 2 #include <algorithm> 3 #define LEFT (segt[cur].l) 4 #define RIGHT (segt[cur].r) 5 #define MID (segt[cur].mid) 6 #define SUM (segt[cur].Sum) 7 #define TAG (segt[cur].Tag) 8 #define LCH (cur << 1) 9 #define RCH ((cur << 1) | 1) 10 11 using namespace std; 12 13 template<typename Type> 14 void Get_Val(Type &Ret) 15 { 16 Ret = 0; 17 char ch; 18 bool Neg(false); 19 while (ch = getchar(), (ch > ‘9‘ || ch < ‘0‘) && ch != ‘-‘) 20 ; 21 if (ch == ‘-‘) 22 { 23 Neg = true; 24 while (ch = getchar(), ch > ‘9‘ || ch < ‘0‘) 25 ; 26 } 27 do 28 { 29 (Ret *= 10) += ch - ‘0‘; 30 } 31 while (ch = getchar(), ch >= ‘0‘ && ch <= ‘9‘); 32 Ret = (Neg ? -Ret : Ret); 33 } 34 35 const int Max_N(100050); 36 const int root(1); 37 38 int N, M; 39 long long int W[Max_N]; 40 int Total, Head[Max_N], To[Max_N << 1], Next[Max_N << 1]; 41 int Dfs_Clock, Father[Max_N], Deep[Max_N], Size[Max_N], Son[Max_N], Top[Max_N], Pre[Max_N], Post[Max_N], ID[Max_N]; 42 43 inline 44 void Add_Edge(const int &s, const int &t) 45 { 46 ++Total; 47 To[Total] = t; 48 Next[Total] = Head[s], Head[s] = Total; 49 } 50 51 struct node 52 { 53 int l, r, mid; 54 long long int Sum, Tag; 55 }; 56 57 struct Segment_Tree 58 { 59 node segt[Max_N << 2]; 60 void build_tree(const int&, const int&, const int&); 61 inline 62 void pushup(const int &cur) 63 { 64 SUM = segt[LCH].Sum + segt[RCH].Sum; 65 } 66 inline 67 void pushdown(const int &cur) 68 { 69 if (TAG) 70 { 71 segt[LCH].Sum += (segt[LCH].r - segt[LCH].l + 1) * TAG; 72 segt[RCH].Sum += (segt[RCH].r - segt[RCH].l + 1) * TAG; 73 segt[LCH].Tag += TAG, segt[RCH].Tag += TAG; 74 TAG = 0; 75 } 76 } 77 void Add(const int&, const int&, const int&, const long long int&); 78 long long int Sum(const int&, const int&, const int&); 79 }; 80 Segment_Tree Tree; 81 82 void Segment_Tree::build_tree(const int &cur, const int &l, const int &r) 83 { 84 LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), TAG = 0; 85 if (l == r) 86 { 87 SUM = W[ID[l]]; 88 return; 89 } 90 build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r); 91 pushup(cur); 92 } 93 94 void Segment_Tree::Add(const int &cur, const int &l, const int &r, const long long int &x) 95 { 96 if (l == LEFT && r == RIGHT) 97 { 98 SUM += (RIGHT - LEFT + 1) * x; 99 TAG += x; 100 return; 101 } 102 pushdown(cur); 103 if (r <= MID) 104 Add(LCH, l, r, x); 105 else 106 if (l > MID) 107 Add(RCH, l, r, x); 108 else 109 Add(LCH, l, MID, x), Add(RCH, MID + 1, r, x); 110 pushup(cur); 111 } 112 113 long long int Segment_Tree::Sum(const int &cur, const int &l, const int &r) 114 { 115 if (l == LEFT && r == RIGHT) 116 return SUM; 117 pushdown(cur); 118 if (r <= MID) 119 return Sum(LCH, l, r); 120 else 121 if (l > MID) 122 return Sum(RCH, l, r); 123 else 124 return Sum(LCH, l, MID) + Sum(RCH, MID + 1, r); 125 } 126 127 void dfs1(const int &u, const int &fa) 128 { 129 Size[u] = 1; 130 int v; 131 for (int i = Head[u];i;i = Next[i]) 132 { 133 v = To[i]; 134 if (v != fa) 135 { 136 Father[v] = u, Deep[v] = Deep[u] + 1; 137 dfs1(v, u); 138 Size[u] += Size[v]; 139 if (Size[v] > Size[Son[u]]) 140 Son[u] = v; 141 } 142 } 143 } 144 145 void dfs2(const int &u) 146 { 147 Pre[u] = Post[u] = ++Dfs_Clock, ID[Dfs_Clock] = u; 148 int v; 149 if (v = Son[u]) 150 { 151 Top[v] = Top[u]; 152 dfs2(v); 153 Post[u] = max(Post[u], Post[v]); 154 } 155 for (int i = Head[u];i;i = Next[i]) 156 { 157 v = To[i]; 158 if (v != Father[u] && v != Son[u]) 159 { 160 Top[v] = v; 161 dfs2(v); 162 Post[u] = max(Post[u], Post[v]); 163 } 164 } 165 } 166 167 void init() 168 { 169 Get_Val(N), Get_Val(M); 170 int fr, to; 171 for (int i = 1;i <= N;++i) 172 Get_Val(W[i]); 173 for (int i = 1;i != N;++i) 174 { 175 Get_Val(fr), Get_Val(to); 176 Add_Edge(fr, to), Add_Edge(to, fr); 177 } 178 Deep[root] = 1, dfs1(root, Father[root] = -1); 179 Top[root] = root, dfs2(root); 180 } 181 182 long long int Query(int u, int v) 183 { 184 long long int Sum(0), r1(Top[u]), r2(Top[v]); 185 while (r1 != r2) 186 { 187 if (Deep[r1] < Deep[r2]) 188 swap(u, v), swap(r1, r2); 189 Sum += Tree.Sum(1, Pre[r1], Pre[u]); 190 u = Father[r1], r1 = Top[u]; 191 } 192 if (Deep[u] > Deep[v]) 193 swap(u, v); 194 return Sum + Tree.Sum(1, Pre[u], Pre[v]); 195 } 196 197 void work() 198 { 199 Tree.build_tree(1, 1, N); 200 int op, x, a; 201 while (M--) 202 { 203 Get_Val(op); 204 if (op == 1) 205 { 206 Get_Val(x), Get_Val(a); 207 Tree.Add(1, Pre[x], Pre[x], a); 208 } 209 if (op == 2) 210 { 211 Get_Val(x), Get_Val(a); 212 Tree.Add(1, Pre[x], Post[x], a); 213 } 214 if (op == 3) 215 { 216 Get_Val(x); 217 printf("%lld\n", Query(x, root)); 218 } 219 } 220 } 221 222 int main() 223 { 224 init(); 225 work(); 226 return 0; 227 }
BZOJ 4196 裸题。。觉得noi考这种数据结构裸题很没有意思啊
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define LEFT (segt[cur].l) 6 #define RIGHT (segt[cur].r) 7 #define MID (segt[cur].mid) 8 #define ZERO (segt[cur].Sum[0]) 9 #define ONE (segt[cur].Sum[1]) 10 #define TAG (segt[cur].Tag) 11 #define LCH (cur << 1) 12 #define RCH ((cur << 1) | 1) 13 14 using namespace std; 15 16 const int Max_N(100050); 17 const int root(1); 18 19 void Get_Val(int &Ret) 20 { 21 Ret = 0; 22 char ch; 23 while (ch = getchar(), ch > ‘9‘ || ch < ‘0‘) 24 ; 25 do 26 { 27 (Ret *= 10) += ch - ‘0‘; 28 } 29 while (ch = getchar(), ch >= ‘0‘ && ch <= ‘9‘); 30 } 31 32 int N; 33 int Total, Head[Max_N], To[Max_N], Next[Max_N]; 34 int Father[Max_N], Deep[Max_N], Size[Max_N], Son[Max_N], Top[Max_N]; 35 int Dfs_Clock, Pre[Max_N], Post[Max_N]; 36 int Degree[Max_N]; 37 38 struct node 39 { 40 int l, r, mid; 41 int Sum[2], Tag; 42 }; 43 44 struct Segment_Tree 45 { 46 node segt[Max_N << 2]; 47 void build_tree(const int&, const int&, const int&); 48 inline 49 void pushup(const int &cur) 50 { 51 ZERO = segt[LCH].Sum[0] + segt[RCH].Sum[0]; 52 ONE = segt[LCH].Sum[1] + segt[RCH].Sum[1]; 53 } 54 inline 55 void pushdown(const int &cur) 56 { 57 if (TAG != -1) 58 { 59 if (TAG) 60 { 61 segt[LCH].Sum[1] = segt[LCH].r - segt[LCH].l + 1; 62 segt[RCH].Sum[1] = segt[RCH].r - segt[RCH].l + 1; 63 segt[LCH].Sum[0] = segt[RCH].Sum[0] = 0; 64 } 65 else 66 { 67 segt[LCH].Sum[0] = segt[LCH].r - segt[LCH].l + 1; 68 segt[RCH].Sum[0] = segt[RCH].r - segt[RCH].l + 1; 69 segt[LCH].Sum[1] = segt[RCH].Sum[1] = 0; 70 } 71 segt[LCH].Tag = segt[RCH].Tag = TAG; 72 TAG = -1; 73 } 74 } 75 int Set(const int&, const int&, const int&, const int&); 76 }; 77 Segment_Tree Tree; 78 79 void Segment_Tree::build_tree(const int &cur, const int &l, const int &r) 80 { 81 LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1); 82 ONE = 0, ZERO = r - l + 1, TAG = -1; 83 if (l == r) 84 return; 85 build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r); 86 } 87 88 int Segment_Tree::Set(const int &cur, const int &l, const int &r, const int &x) 89 { 90 int Ans; 91 if (l == LEFT && r == RIGHT) 92 { 93 Ans = segt[cur].Sum[1 - x]; 94 if (x) 95 ONE = RIGHT - LEFT + 1, ZERO = 0; 96 else 97 ZERO = RIGHT - LEFT + 1, ONE = 0; 98 TAG = x; 99 return Ans; 100 } 101 pushdown(cur); 102 if (r <= MID) 103 { 104 Ans = Set(LCH, l, r, x); 105 pushup(cur); 106 } 107 else 108 if (l > MID) 109 { 110 Ans = Set(RCH, l, r, x); 111 pushup(cur); 112 } 113 else 114 { 115 Ans = Set(LCH, l, MID, x) + Set(RCH, MID + 1, r, x); 116 pushup(cur); 117 } 118 return Ans; 119 } 120 121 inline 122 void Add_Edge(const int &s, const int &t) 123 { 124 ++Total; 125 To[Total] = t; 126 Next[Total] = Head[s], Head[s] = Total; 127 } 128 129 void bfs1() 130 { 131 queue<int> Q; 132 int u, fa; 133 for (int i = 1;i <= N;++i) 134 if (!Degree[i]) 135 Q.push(i); 136 while (Q.size()) 137 { 138 u = Q.front(), Q.pop(); 139 fa = Father[u]; 140 ++Size[u]; 141 if (u != root) 142 { 143 Size[fa] += Size[u]; 144 if (Size[u] > Size[Son[fa]]) 145 Son[fa] = u; 146 Add_Edge(fa, u); 147 if ((--Degree[fa]) == 0) 148 Q.push(fa); 149 } 150 } 151 } 152 153 void dfs2(const int &u) 154 { 155 int v; 156 Pre[u] = Post[u] = ++Dfs_Clock; 157 if (v = Son[u]) 158 { 159 Top[v] = Top[u]; 160 Deep[v] = Deep[u] + 1; 161 dfs2(v); 162 Post[u] = Post[v]; 163 } 164 for (int i = Head[u];i;i = Next[i]) 165 if ((v = To[i]) != Son[u]) 166 { 167 Top[v] = v; 168 Deep[v] = Deep[u] + 1; 169 dfs2(v); 170 Post[u] = Post[v]; 171 } 172 } 173 174 void init() 175 { 176 Get_Val(N); 177 for (int i = 2;i <= N;++i) 178 Get_Val(Father[i]), ++Father[i], ++Degree[Father[i]]; 179 Father[root] = -1, bfs1(); 180 Deep[root] = 1, Top[root] = root, dfs2(root); 181 } 182 183 int Query(int u, int v) 184 { 185 int Ans(0), r1(Top[u]), r2(Top[v]); 186 while (r1 != r2) 187 { 188 if (Deep[r1] < Deep[r2]) 189 swap(r1, r2), swap(u, v); 190 Ans += Tree.Set(1, Pre[r1], Pre[u], 1); 191 u = Father[r1], r1 = Top[u]; 192 } 193 if (Deep[u] > Deep[v]) 194 swap(u, v); 195 return Ans + Tree.Set(1, Pre[u], Pre[v], 1); 196 } 197 198 void work() 199 { 200 int Q, x; 201 Get_Val(Q); 202 char op[20]; 203 Tree.build_tree(1, 1, N); 204 while (Q--) 205 { 206 scanf("%s", op); 207 Get_Val(x); 208 ++x; 209 if (*op == ‘i‘) 210 printf("%d\n", Query(x, root)); 211 else 212 printf("%d\n", Tree.Set(1, Pre[x], Post[x], 0)); 213 } 214 } 215 216 int main() 217 { 218 init(); 219 work(); 220 return 0; 221 }
标签:
原文地址:http://www.cnblogs.com/Created-equal/p/5204153.html