记录编号 144834 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 1.281 s
提交时间 2014-12-29 22:46:56 内存使用 4.09 MiB
显示代码纯文本
  1. /*====================Asm.Def========================*/
  2. #include <iostream>
  3. #include <cctype>
  4. #include <cstdio>
  5. #include <cstdlib>
  6. #include <algorithm>
  7. #include <ctime>
  8. using namespace std;
  9. inline void getd(int &x){
  10. char c = getchar();bool minus = 0;
  11. while(!isdigit(c) && c != '-')c = getchar();
  12. if(c == '-')minus = 1, c = getchar();
  13. x = c - '0';
  14. while(isdigit(c = getchar()))x = x * 10 + c - '0';
  15. if(minus)x = -x;
  16. }
  17. /*======================================================*/
  18. const int maxn = 30005, INF = 0x7fffffff;
  19. int N, Val[maxn];
  20. struct SegT{
  21. SegT *son[2];
  22. int L, R, mid, Sum, Max;
  23. inline void update(){
  24. Sum = son[0]->Sum + son[1]->Sum;
  25. Max = max(son[0]->Max, son[1]->Max);
  26. }
  27. inline void init(int, int);
  28. inline void Set(int i, int x){
  29. if(L == R){Sum = Max = x;return;}
  30. if(i <= mid)son[0]->Set(i, x);
  31. else son[1]->Set(i, x);
  32. update();
  33. }
  34. inline int qsum(int l, int r){
  35. if(l == L && r == R)return Sum;
  36. if(r <= mid)return son[0]->qsum(l, r);
  37. if(l > mid)return son[1]->qsum(l, r);
  38. return son[0]->qsum(l, mid) + son[1]->qsum(mid+1, r);
  39. }
  40. inline int qmax(int l, int r){
  41. if(l == L && r == R)return Max;
  42. if(r <= mid)return son[0]->qmax(l, r);
  43. if(l > mid)return son[1]->qmax(l, r);
  44. return max(son[0]->qmax(l, mid), son[1]->qmax(mid+1, r));
  45. }
  46. }Seg, Segnode[maxn << 2];
  47.  
  48. inline void SegT::init(int l, int r){
  49. static int Segptr = 0;
  50. L = l, R = r, mid = (l + r) >> 1;
  51. if(L == R){
  52. Sum = Max = Val[L];
  53. if(L == 0)Max = -INF;
  54. son[0] = son[1] = NULL;
  55. return;
  56. }
  57. son[0] = Segnode + Segptr++;son[1] = Segnode + Segptr++;
  58. son[0]->init(l, mid), son[1]->init(mid+1, r);
  59. Max = max(son[0]->Max, son[1]->Max);
  60. Sum = son[0]->Sum + son[1]->Sum;
  61. }
  62.  
  63. struct Node{
  64. struct Eto{Node *to;Eto *next;Eto(Node *t):to(t){};};
  65. Eto *adj;
  66. Node *Son, *pre, *anc;
  67. int dep, size, val, Loc/*在Seg中的位置*/;
  68. inline void Addadj(Node *to){Eto *t = new Eto(to);t->next = adj;adj = t;}
  69. inline void dfs(){
  70. register Eto *it;
  71. register Node *t;
  72. size = 1;
  73. register int MaxS = 0;
  74. for(it = adj;it != NULL;it = it->next){
  75. t = it->to;
  76. if(t == pre)continue;
  77. t->pre = this;t->dep = dep + 1;
  78. t->dfs();
  79. size += t->size;
  80. if(t->size > MaxS)Son = t, MaxS = t->size;
  81. }
  82. }
  83. inline void build(){//注意SegT 0位置的Max = -INF
  84. register Eto *it;
  85. register Node *t;
  86. static int iter = 1;
  87. Loc = iter;
  88. Val[iter++] = val;
  89. if(Son == NULL)return;
  90. Son->anc = anc;
  91. Son->build();
  92. for(it = adj;it != NULL;it = it->next){
  93. t = it->to;
  94. if(t == pre || t == Son)continue;
  95. t->anc = t;
  96. t->build();
  97. }
  98. }
  99. }node[maxn];
  100.  
  101. inline void init(){
  102. getd(N);
  103. register int i, a, b;
  104. for(i = 1;i < N;++i){
  105. getd(a), getd(b);
  106. node[a].Addadj(node + b);
  107. node[b].Addadj(node + a);
  108. }
  109. for(i = 1;i <= N;++i)
  110. getd(node[i].val);
  111. srand(time(NULL));
  112. register Node *root = node + (rand() % N + 1);
  113. root->pre = node, root->dep = 1;
  114. root->dfs();
  115. root->anc = root;
  116. root->build();
  117. Seg.init(1, N);
  118. }
  119.  
  120. inline int Qsum(int a, int b){
  121. Node *u = node + a, *v = node + b;
  122. int ans = 0;
  123. while(u->anc != v->anc){
  124. if(u->anc->dep < v->anc->dep)swap(u, v);
  125. ans += Seg.qsum(u->anc->Loc, u->Loc);
  126. u = u->anc->pre;
  127. }
  128. if(u->Loc > v->Loc)swap(u, v);
  129. ans += Seg.qsum(u->Loc, v->Loc);
  130. return ans;
  131. }
  132.  
  133. inline int Qmax(int a, int b){
  134. Node *u = node + a, *v = node + b;
  135. int ans = -INF;
  136. while(u->anc != v->anc){
  137. if(u->anc->dep < v->anc->dep)swap(u, v);
  138. ans = max(ans, Seg.qmax(u->anc->Loc, u->Loc));
  139. u = u->anc->pre;
  140. }
  141. if(u->dep < v->dep)swap(u, v);
  142. ans = max(ans, Seg.qmax(v->Loc, u->Loc));
  143. return ans;
  144. }
  145.  
  146. int main(){
  147. #if defined DEBUG
  148. freopen("test", "r", stdin);
  149. freopen("output.txt", "w", stdout);
  150. #else
  151. freopen("bzoj_1036.in", "r", stdin);
  152. freopen("bzoj_1036.out", "w", stdout);
  153. #endif
  154. init();
  155. register int T, a, b;
  156. char opt[10], *End;
  157. getd(T);
  158. while(T--){
  159. End = opt;
  160. while(!isalpha(*End = getchar()));++End;
  161. while(isalpha(*End = getchar()))++End;
  162. getd(a), getd(b);
  163. if(End - opt == 6)//Change
  164. Seg.Set(node[a].Loc, b);
  165. else if(opt[1] == 'M')//QMAX
  166. printf("%d\n", Qmax(a, b));
  167. else//QSUM
  168. printf("%d\n", Qsum(a, b));
  169. }
  170. #if defined DEBUG
  171. cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
  172. #endif
  173. return 0;
  174. }