记录编号 365523 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015] 树黑白 最终得分 100
用户昵称 Gravatar‎MistyEye 是否通过 通过
代码语言 C++ 运行时间 0.687 s
提交时间 2017-01-20 19:25:27 内存使用 72.03 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cctype>
  6. using namespace std;
  7. int read() {
  8. int x=0; char ch;
  9. while(ch=getchar(), !isdigit(ch));
  10. x = ch-'0';
  11. while(ch=getchar(), isdigit(ch)) x = x*10+ch-'0';
  12. return x;
  13. }
  14. const int maxn = 200005, maxd = 20;
  15. struct Edge {
  16. int next, to, dis;
  17. Edge(int a=0, int b=0, int c=0) :
  18. next(a), to(b), dis(c) {}
  19. } e[maxn<<1];
  20. int head[maxn], tot;
  21. void Add(int u, int v, int w) {
  22. e[++tot] = Edge(head[u], v, w); head[u] = tot;
  23. }
  24. int N, Q, F, Size, root, size[maxn], vis[maxn];
  25. int fa[maxn], res[maxn];
  26. int dis[maxn][maxd], sub[maxn][maxd];
  27. int sum[maxn], num[maxn], black[maxn];
  28. int sums[maxn][maxd], nums[maxn][maxd];
  29.  
  30. void invert(int x) {
  31. black[x] ^= 1;
  32. int mk = black[x] ? 1 : -1;
  33. num[x] += mk;
  34. for(int y=fa[x], r=res[x]-1; y; y=fa[y], --r) {
  35. num[y] += mk;
  36. sum[y] += mk*dis[x][r];
  37. nums[sub[x][r]][r] += mk;
  38. sums[sub[x][r]][r] += mk*dis[x][r];
  39. }
  40. }
  41. int query(int x) {
  42. int ans = sum[x]; //warn
  43. for(int y=fa[x], r=res[x]-1; y; y=fa[y], --r) {
  44. ans += sum[y]-sums[sub[x][r]][r];
  45. ans += dis[x][r]*(num[y]-nums[sub[x][r]][r]);
  46. }
  47. return ans;
  48. }
  49. void getdep(int x, int fa, int Sub, int Res) {
  50. sub[x][Res] = Sub;
  51. for(int i=head[x]; i; i=e[i].next) {
  52. int to = e[i].to;
  53. if(vis[to] || to==fa) continue;
  54. dis[to][Res] = dis[x][Res]+e[i].dis;
  55. getdep(to, x, Sub, Res);
  56. }
  57. }
  58. void build(int x) {
  59. for(int i=head[x]; i; i=e[i].next) {
  60. int to = e[i].to;
  61. if(vis[to]) continue;
  62. dis[to][res[x]] = e[i].dis;
  63. getdep(to, x, to, res[x]);
  64. }
  65. }
  66. int getroot(int x, int fa) {
  67. int f = 0; size[x] = 1;
  68. for(int i=head[x]; i; i=e[i].next) {
  69. int to = e[i].to;
  70. if(vis[to] || to==fa) continue;
  71. size[x] += getroot(to, x);
  72. f = max(f, size[to]);
  73. }
  74. f = max(f, Size-size[x]);
  75. if(f<=F) F = f, root = x;
  76. return size[x];
  77. }
  78. void Build(int x) {
  79. vis[x] = 1; build(x);
  80. for(int i=head[x]; i; i=e[i].next) {
  81. int to = e[i].to;
  82. if(vis[to]) continue;
  83. F = Size = size[to]; getroot(to, -1);
  84. fa[root] = x;
  85. res[root] = res[x]+1;
  86. Build(root);
  87. }
  88. }
  89. int main() {
  90. freopen("A_Tree.in","r",stdin);
  91. freopen("A_Tree.out","w",stdout);
  92. N = read(), Q = read();
  93. for(int i=1,a,b,c; i<N; ++i) {
  94. a = read(), b = read(), c = read();
  95. Add(a, b, c); Add(b, a, c);
  96. }
  97. F = Size = N; getroot(1, -1);
  98. res[root] = 1, Build(root);
  99. char ch[2]; int v;
  100. while(Q--) {
  101. scanf("%s", ch); v = read();
  102. if(ch[0]=='Q') printf("%d\n", query(v));
  103. else invert(v);
  104. }
  105. getchar(), getchar();
  106. return 0;
  107. }