记录编号 563522 评测结果 AAAAAAAAAA
题目名称 异象石 最终得分 100
用户昵称 Gravataryrtiop 是否通过 通过
代码语言 C++ 运行时间 0.740 s
提交时间 2021-08-19 12:05:50 内存使用 12.63 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn = 100005;
  6. const int INF = 1e9;
  7. typedef long long ll;
  8. ll ans = 0;
  9. int n,m;
  10. int tot;
  11. int point[maxn];
  12. int head[maxn],ver[maxn << 1],nxt[maxn << 1];
  13. ll cost[maxn << 1];
  14. void add(int u,int v,int t) {
  15. ver[++ tot] = v;
  16. nxt[tot] = head[u];
  17. cost[tot] = t;
  18. head[u] = tot;
  19. return ;
  20. }
  21. int rt,sz;
  22. int son[maxn][2],size[maxn],key[maxn],rd[maxn],cnt[maxn];
  23. int pos[maxn];
  24. void pushup(int x) {
  25. size[x] = size[son[x][0]] + size[son[x][1]] + cnt[x];
  26. return ;
  27. }
  28. void rotate(int &x,int d) {
  29. int k = son[x][d ^ 1];
  30. son[x][d ^ 1] = son[k][d];
  31. son[k][d] = x;
  32. pushup(x);
  33. pushup(k);
  34. x = k;
  35. return ;
  36. }
  37. void insert(int &p,int x) {
  38. if(!p) {
  39. p = ++ sz;
  40. size[p] = cnt[p] = 1;
  41. son[p][0] = son[p][1] = 0;
  42. key[p] = x;
  43. rd[p] = rand();
  44. return ;
  45. }
  46. if(key[p] == x) {
  47. ++ cnt[p];
  48. ++ size[p];
  49. return ;
  50. }
  51. int d = x > key[p];
  52. insert(son[p][d] , x);
  53. if(rd[p] < rd[son[p][d]]) {
  54. rotate(p , d ^ 1);
  55. }
  56. pushup(p);
  57. return ;
  58. }
  59. void remove(int &p,int x) {
  60. if(!p)return ;
  61. if(key[p] != x) {
  62. remove(son[p][x > key[p]] , x);
  63. }
  64. else {
  65. if(!son[p][0]&&!son[p][1]) {
  66. -- cnt[p];
  67. -- size[p];
  68. if(!cnt[p]) {
  69. p = 0;
  70. }
  71. }
  72. else if(son[p][0]&&!son[p][1]) {
  73. rotate(p , 1);
  74. remove(son[p][1] , x);
  75. }
  76. else if(!son[p][0]&&son[p][1]) {
  77. rotate(p , 0);
  78. remove(son[p][0] , x);
  79. }
  80. else {
  81. int d = rd[son[p][0]] > rd[son[p][1]];
  82. rotate(p , d);
  83. remove(son[p][d] , x);
  84. }
  85. }
  86. pushup(p);
  87. return ;
  88. }
  89. int pre(int p,int x) {
  90. if(!p)return -INF;
  91. if(key[p] >= x)return pre(son[p][0] , x);
  92. else return max(key[p] , pre(son[p][1] , x));
  93. }
  94. int suff(int p,int x) {
  95. if(!p)return INF;
  96. if(key[p] <= x)return suff(son[p][1] , x);
  97. else return min(key[p] , suff(son[p][0] , x));
  98. }
  99. int Minimum(int p) {
  100. if(!son[p][0])return key[p];
  101. return Minimum(son[p][0]);
  102. }
  103. int Maximum(int p) {
  104. if(!son[p][1])return key[p];
  105. return Maximum(son[p][1]);
  106. }
  107. int lg[maxn],f[maxn][20];
  108. int d[maxn];
  109. ll dis[maxn];
  110. int dfn[maxn];
  111. int LCA(int u,int v) {
  112. if(d[u] < d[v])swap(u , v);
  113. for(int k = lg[d[u]];~ k;-- k) {
  114. if(d[u] - (1 << k) >= d[v]) {
  115. u = f[u][k];
  116. }
  117. if(u == v)return u;
  118. }
  119. if(u == v)return u;
  120. for(int k = lg[d[u]];~ k;-- k) {
  121. if(f[u][k] != f[v][k]) {
  122. u = f[u][k];
  123. v = f[v][k];
  124. }
  125. }
  126. return f[u][0];
  127. }
  128. ll dist(int u,int v) {
  129. return dis[u] + dis[v] - (dis[LCA(u , v)] << 1);
  130. }
  131. void LCApre(int u,int d) {
  132. for(int k = 1;k <= lg[d];++ k)f[u][k] = f[f[u][k - 1]][k - 1];
  133. return ;
  134. }
  135. void dfs(int u) {
  136. pos[dfn[u] = ++ tot] = u;
  137. for(int i = head[u];i;i = nxt[i]) {
  138. int v = ver[i];
  139. if(dfn[v])continue ;
  140. f[v][0] = u;
  141. d[v] = d[u] + 1;
  142. dis[v] = dis[u] + cost[i];
  143. LCApre(v , d[v]);
  144. dfs(v);
  145. }
  146. return ;
  147. }
  148. int main() {
  149. freopen("visionstone.in","r",stdin);
  150. freopen("visionstone.out","w",stdout);
  151. scanf("%d",&n);
  152. for(int i = 2;i <= n;++ i) {
  153. int u,v,t;
  154. scanf("%d%d%d",&u,&v,&t);
  155. add(u , v , t);
  156. add(v , u , t);
  157. lg[i] = lg[i >> 1] + 1;
  158. }
  159. tot = 0;
  160. dfs(1);
  161. scanf("%d",&m);
  162. for(int i = 1;i <= m;++ i) {
  163. char op;
  164. scanf(" %c",&op);
  165. if(op == '+') {
  166. int u;
  167. scanf("%d",&u);
  168. if(sz) {
  169. int x1 = pre(rt , dfn[u]),x2 = suff(rt , dfn[u]);
  170. if(x1 == -1e9)x1 = Maximum(rt);
  171. if(x2 == 1e9)x2 = Minimum(rt);
  172. int p = pos[x1],s = pos[x2];
  173. ans -= dist(p , s);
  174. ans += dist(p , u) + dist(u , s);
  175. }
  176. insert(rt , dfn[u]);
  177. }
  178. else if(op == '-') {
  179. int u;
  180. scanf("%d",&u);
  181. int x1 = pre(rt , dfn[u]),x2 = suff(rt , dfn[u]);
  182. if(x1 == -1e9)x1 = Maximum(rt);
  183. if(x2 == 1e9)x2 = Minimum(rt);
  184. int p = pos[x1],s = pos[x2];
  185. ans += dist(p , s);
  186. ans -= dist(p , u) + dist(u , s);
  187. remove(rt , dfn[u]);
  188. }
  189. else {
  190. printf("%lld\n",ans >> 1);
  191. }
  192. }
  193. fclose(stdin);
  194. fclose(stdout);
  195. return 0;
  196. }