记录编号 279056 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015]疯狂的魔法树 最终得分 100
用户昵称 GravatarAglove 是否通过 通过
代码语言 C++ 运行时间 1.804 s
提交时间 2016-07-08 19:31:23 内存使用 14.04 MiB
显示代码纯文本
  1. #define MAXN 200010UL
  2. #include <vector>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6.  
  7. #define rep(i, x, y) for(int i = (x) ; i <= (y) ; ++ i)
  8. #define der(i, x, y) for(int i = (x) ; i >= (y) ; -- i)
  9. #define reg(i, x) for(int i = d[x] ; i != -1 ; i = sg[i].nt)
  10. #define fir first
  11. #define sec second
  12. #define mp make_pair
  13. #define pb push_back
  14.  
  15. using namespace std;
  16.  
  17. int n, m, blo, tot = 1, a, b, ans, val, nw, add[MAXN], pos[MAXN], vis[MAXN], fa[MAXN], c[MAXN];
  18. vector <int> v[MAXN];
  19. char s[10];
  20.  
  21. struct Graph {
  22. int d[MAXN], t;
  23. Graph() { memset(d, -1, sizeof(d)); }
  24. struct Edge { int hou, nt; } sg[MAXN<<1];
  25. void Add_edge(int x, int y) {
  26. sg[t] = (Edge){y, d[x]}, d[x] = t ++;
  27. return;
  28. }
  29. }G, T;
  30.  
  31. bool cmp(const int &a, const int &b) {
  32. return c[a]<c[b];
  33. }
  34.  
  35. void Get_block(int x, int _fa) {
  36. fa[x] = _fa;
  37. if(v[pos[_fa]].size()==blo) {
  38. ++ tot, pos[x] = tot;
  39. T.Add_edge(pos[_fa], tot);
  40. v[tot].push_back(x);
  41. } else pos[x] = pos[_fa], v[pos[x]].push_back(x);
  42. for(int i = G.d[x] ; i != -1 ; i = G.sg[i].nt) {
  43. if(G.sg[i].hou==_fa) continue;
  44. Get_block(G.sg[i].hou, x);
  45. }
  46. return;
  47. }
  48.  
  49. int Get_up(vector <int> &v, int val) {
  50. int L = 0, R = v.size()-1;
  51. if(c[v[0]]>val) return -1;
  52. int ret = -1;
  53. while(L<=R) {
  54. int mid = (L+R)>>1;
  55. if(c[v[mid]]<=val) L = mid+1, ret = mid;
  56. else R = mid-1;
  57. }
  58. return ret;
  59. }
  60.  
  61. int Get_low(vector <int> &v, int val) {
  62. int L = 0, R = v.size()-1;
  63. if(c[v[R]]<val) return -1;
  64. int ret = -1;
  65. while(L<=R) {
  66. int mid = (L+R)>>1;
  67. if(c[v[mid]]>=val) ret = mid, R = mid-1;
  68. else L = mid+1;
  69. }
  70. return ret;
  71. }
  72.  
  73. int Judge(int x) {
  74. if(vis[x]) {
  75. if(vis[x]>=a&&vis[x]<=b) return v[x].size();
  76. else return 0;
  77. }
  78. int L = Get_low(v[x], a-add[x]);
  79. int R = Get_up(v[x], b-add[x]);
  80. if(L==-1||R==-1) return 0;
  81. return R-L+1;
  82. }
  83.  
  84. void Dfs_block(int x) {
  85. ans += Judge(x);
  86. for(int i = T.d[x] ; i != -1 ; i = T.sg[i].nt) Dfs_block(T.sg[i].hou);
  87. return;
  88. }
  89.  
  90. void Dfs_point(int x) {
  91. if(c[x]+add[pos[x]]>=a&&c[x]+add[pos[x]]<=b) ++ ans;
  92. for(int i = G.d[x] ; i != -1 ; i = G.sg[i].nt) {
  93. int nxt = G.sg[i].hou;
  94. if(nxt==fa[x]) continue;
  95. if(pos[nxt]==pos[x]) Dfs_point(nxt);
  96. else Dfs_block(pos[nxt]);
  97. }
  98. return;
  99. }
  100.  
  101. void Block_add(int x) {
  102. if(vis[x]) vis[x] += val;
  103. else add[x] += val;
  104. for(int i = T.d[x] ; i != -1 ; i = T.sg[i].nt) Block_add(T.sg[i].hou);
  105. return;
  106. }
  107.  
  108. void Point_add(int x) {
  109. c[x] += val;
  110. for(int i = G.d[x] ; i != -1 ; i = G.sg[i].nt) {
  111. int nxt = G.sg[i].hou;
  112. if(nxt==fa[x]) continue;
  113. if(pos[nxt]==pos[x]) Point_add(nxt);
  114. else Block_add(pos[nxt]);
  115. }
  116. return;
  117. }
  118.  
  119. void Block_modify(int x) {
  120. add[x] = 0, vis[x] = val;
  121. for(int i = T.d[x] ; i != -1 ; i = T.sg[i].nt) Block_modify(T.sg[i].hou);
  122. return;
  123. }
  124.  
  125. void Point_modify(int x) {
  126. c[x] = val-add[pos[x]];
  127. for(int i = G.d[x] ; i != -1 ; i = G.sg[i].nt) {
  128. int nxt = G.sg[i].hou;
  129. if(nxt==fa[x]) continue;
  130. if(pos[nxt]==pos[x]) Point_modify(nxt);
  131. else Block_modify(pos[nxt]);
  132. }
  133. return;
  134. }
  135.  
  136. void Push_down(int x) {
  137. int siz = v[x].size();
  138. rep(i, 0, siz-1) c[v[x][i]] = vis[x];
  139. vis[x] = 0;
  140. return;
  141. }
  142.  
  143. int main() {
  144. freopen("H_Tree.in", "r", stdin);
  145. freopen("H_Tree.out", "w", stdout);
  146. int x, y;
  147. scanf("%d%d", &n, &m);
  148. rep(i, 1, n) scanf("%d", &c[i]);
  149. rep(i, 2, n) scanf("%d%d", &x, &y), G.Add_edge(x, y), G.Add_edge(y, x);
  150. blo = 250, pos[0] = 1, Get_block(1, 0);
  151. rep(i, 1, tot) sort(v[i].begin(), v[i].end(), cmp);
  152. while(m --) {
  153. scanf("%s", s);
  154. if(*s=='Q') {
  155. scanf("%d%d%d", &x, &a, &b);
  156. ans = 0, nw = pos[x];
  157. if(vis[nw]) Push_down(nw);
  158. Dfs_point(x);
  159. printf("%d\n", ans);
  160. } else if(*s=='M') {
  161. scanf("%d%d", &x, &val);
  162. nw = pos[x];
  163. if(vis[nw]) Push_down(nw);
  164. c[x] = val-add[nw];
  165. sort(v[nw].begin(), v[nw].end(), cmp);
  166. } else if(*s=='C') {
  167. scanf("%d%d", &x, &val);
  168. nw = pos[x];
  169. if(vis[nw]) Push_down(nw);
  170. Point_add(x);
  171. sort(v[nw].begin(), v[nw].end(), cmp);
  172. } else if(*s=='W') {
  173. scanf("%d%d", &x, &val);
  174. nw = pos[x];
  175. if(vis[nw]) Push_down(nw);
  176. Point_modify(x);
  177. sort(v[nw].begin(), v[nw].end(), cmp);
  178. } else {
  179. int x, y;
  180. scanf("%d%d", &x, &y);
  181. ++ n, fa[n] = x, c[n] = y;
  182. G.Add_edge(x, n);
  183. if(v[pos[x]].size()==blo) {
  184. ++ tot, pos[n] = tot;
  185. T.Add_edge(pos[x], tot);
  186. v[tot].push_back(n);
  187. } else {
  188. nw = pos[x];
  189. if(vis[nw]) Push_down(nw);
  190. pos[n] = pos[x], c[n] = y-add[nw];
  191. v[nw].push_back(n);
  192. sort(v[nw].begin(), v[nw].end(), cmp);
  193. }
  194. }
  195. }
  196. return 0;
  197. }
  198.