1036: [ZJOI2008]树的统计Count

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 11102  Solved: 4490
[Submit][Status][Discuss]

Description

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

Input

输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

Output

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

Sample Input

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4

Sample Output

4
1
2
2
10
6
5
6
5
16

HINT

 

Source

 题解:
树链剖分或LCT模版题。
我写了个树剖:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define lson k*2,l,mid
  4. #define rson k*2+1,mid+1,r
  5. #define MAXN 30010
  6. #define INF 1e9
  7. struct node
  8. {
  9. int begin,end,next;
  10. }edge[MAXN*];
  11. struct NODE
  12. {
  13. int left,right,sum,mx,val;
  14. }tree[*MAXN];
  15. int cnt,Head[MAXN],val[MAXN],deep[MAXN],size[MAXN],P[MAXN][],belong[MAXN],pos[MAXN],SIZE,n;
  16. bool vis[MAXN];
  17. void addedge(int bb,int ee)
  18. {
  19. edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
  20. }
  21. void addedge1(int bb,int ee)
  22. {
  23. addedge(bb,ee);addedge(ee,bb);
  24. }
  25. int read()
  26. {
  27. int s=,fh=;char ch=getchar();
  28. while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
  29. while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
  30. return s*fh;
  31. }
  32. void dfs1(int u)
  33. {
  34. int i,v;
  35. size[u]=;vis[u]=true;
  36. for(i=Head[u];i!=-;i=edge[i].next)
  37. {
  38. v=edge[i].end;
  39. if(vis[v]==false)
  40. {
  41. deep[v]=deep[u]+;
  42. P[v][]=u;
  43. dfs1(v);
  44. size[u]+=size[v];
  45. }
  46. }
  47. }
  48. void Ycl()
  49. {
  50. int i,j;
  51. for(j=;(<<j)<=n;j++)
  52. {
  53. for(i=;i<=n;i++)
  54. {
  55. if(P[i][j-]!=-)P[i][j]=P[P[i][j-]][j-];
  56. }
  57. }
  58. }
  59. void dfs2(int u,int chain)
  60. {
  61. int k=,i,v;
  62. pos[u]=++SIZE;belong[u]=chain;
  63. for(i=Head[u];i!=-;i=edge[i].next)
  64. {
  65. v=edge[i].end;
  66. if(deep[v]>deep[u]&&size[v]>size[k])k=v;
  67. }
  68. if(k==)return;
  69. dfs2(k,chain);
  70. for(i=Head[u];i!=-;i=edge[i].next)
  71. {
  72. v=edge[i].end;
  73. if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
  74. }
  75. }
  76. int LCA(int x,int y)
  77. {
  78. int i,j;
  79. if(deep[x]<deep[y])swap(x,y);
  80. for(i=;(<<i)<=deep[x];i++);i--;
  81. for(j=i;j>=;j--)if(deep[x]-(<<j)>=deep[y])x=P[x][j];
  82. if(x==y)return x;
  83. for(j=i;j>=;j--)
  84. {
  85. if(P[x][j]!=-&&P[x][j]!=P[y][j])
  86. {
  87. x=P[x][j];
  88. y=P[y][j];
  89. }
  90. }
  91. return P[x][];
  92. }
  93. void Pushup(int k)
  94. {
  95. tree[k].sum=tree[k*].sum+tree[k*+].sum;
  96. tree[k].mx=max(tree[k*].mx,tree[k*+].mx);
  97. }
  98. void Build(int k,int l,int r)
  99. {
  100. tree[k].left=l;tree[k].right=r;
  101. if(l==r)return;
  102. int mid=(l+r)/;
  103. Build(lson);
  104. Build(rson);
  105. }
  106. void Change(int k,int P,int V)
  107. {
  108. if(tree[k].left==tree[k].right)
  109. {
  110. tree[k].val=tree[k].sum=tree[k].mx=V;
  111. return;
  112. }
  113. int mid=(tree[k].left+tree[k].right)/;
  114. if(P<=mid)Change(k*,P,V);
  115. else Change(k*+,P,V);
  116. Pushup(k);
  117. }
  118. int Query_max(int k,int l,int r)
  119. {
  120. if(l<=tree[k].left&&tree[k].right<=r)return tree[k].mx;
  121. int mid=(tree[k].left+tree[k].right)/;
  122. if(r<=mid)return Query_max(k*,l,r);
  123. else if(l>mid)return Query_max(k*+,l,r);
  124. else return max(Query_max(k*,l,mid),Query_max(k*+,mid+,r));
  125. }
  126. int Query_sum(int k,int l,int r)
  127. {
  128. if(l<=tree[k].left&&tree[k].right<=r)return tree[k].sum;
  129. int mid=(tree[k].left+tree[k].right)/;
  130. if(r<=mid)return Query_sum(k*,l,r);
  131. else if(l>mid)return Query_sum(k*+,l,r);
  132. else return Query_sum(k*,l,mid)+Query_sum(k*+,mid+,r);
  133. }
  134. int solve_max(int x,int f)
  135. {
  136. int MAX=-INF;
  137. while(belong[x]!=belong[f])
  138. {
  139. MAX=max(MAX,Query_max(,pos[belong[x]],pos[x]));
  140. x=P[belong[x]][];
  141. }
  142. MAX=max(MAX,Query_max(,pos[f],pos[x]));
  143. return MAX;
  144. }
  145. int solve_sum(int x,int f)
  146. {
  147. int SUM=;
  148. while(belong[x]!=belong[f])
  149. {
  150. SUM+=Query_sum(,pos[belong[x]],pos[x]);
  151. x=P[belong[x]][];
  152. }
  153. SUM+=Query_sum(,pos[f],pos[x]);
  154. return SUM;
  155. }
  156. int main()
  157. {
  158. freopen("bzoj_1036.in","r",stdin);
  159. freopen("bzoj_1036.out","w",stdout);
  160. int m,i,bb,ee,u,v,t,lca;
  161. char zs[];
  162. n=read();
  163. memset(Head,-,sizeof(Head));cnt=;
  164. for(i=;i<n;i++)
  165. {
  166. bb=read();ee=read();addedge1(bb,ee);
  167. }
  168. memset(P,-,sizeof(P));SIZE=;
  169. dfs1();Ycl();
  170. dfs2(,);
  171. for(i=;i<=n;i++)val[i]=read();
  172. Build(,,n);
  173. for(i=;i<=n;i++)Change(,pos[i],val[i]);
  174. m=read();
  175. for(i=;i<=m;i++)
  176. {
  177. scanf("\n%s",zs);
  178. if(zs[]=='C'){u=read();t=read();val[u]=t;Change(,pos[u],val[u]);}
  179. else
  180. {
  181. if(zs[]=='M')
  182. {
  183. u=read();v=read();
  184. lca=LCA(u,v);
  185. printf("%d\n",max(solve_max(u,lca),solve_max(v,lca)));
  186. }
  187. else {u=read();v=read();lca=LCA(u,v);printf("%d\n",solve_sum(u,lca)+solve_sum(v,lca)-val[lca]);}
  188. }
  189. }
  190. fclose(stdin);
  191. fclose(stdout);
  192. return ;
  193. }

Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT的更多相关文章

  1. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  2. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  3. bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 16294  Solved: 6645[Submit ...

  4. BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit ...

  5. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)

    [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14968  Solved: 6079[Submit][Stat ...

  6. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  7. bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

    [ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...

  8. Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)

    [ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...

  9. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

随机推荐

  1. 配置php连接apache

    配置php连接apache 1.安装php所需要的库 yum install zlib-devel libxml2-devel libjpeg-devel libjpeg-turbo-devel li ...

  2. scp 命令使用

    scp 是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且 scp传输是加密的.可能会稍微影响一下速度.当你服 ...

  3. nfs,ftp配置

    一. NFS1. NFS简介NFS全称是network file systemNFS允许一个系统在网络上与他人共享目录和文件.通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件. 假 ...

  4. zlib1.2.8 编译小记

    官网下载:http://www.zlib.net/ 用vs命令行工具运行zlib-1.2.8\contrib\masmx86\bld_ml32.bat 用vs2012打开zlib-1.2.8\cont ...

  5. HTML5:一个拖拽网页元素的例子

    关键字:HTML5, Drag&Drop, JavaScript, CSS 运行环境:Chrome <!DOCTYPE html> <html> <head> ...

  6. sqlsever2008数据库的备份与还原

    本文数据库的名称为ProjectControl  public static SqlConnection conn = new SqlConnection("server=(local);u ...

  7. NS实现采用的技术大多是PHP,如果采用java、 .net是否同样适用?

    SNS采用的技术可不都是PHP (不局限于国内),特别是国外的新兴公司,基本上没有再用PHP的了,国内到还是蛮常用的.简单说说我知道的几个案例:Facebook (PHP):Facebook采用PHP ...

  8. 关于Java(Hello World程序)

    详解 Hello World 应用程序 源码 class HelloWorldApp { public static void main(String[] args) { System.out.pri ...

  9. bzoj 1187: [HNOI2007]神奇游乐园 插头dp

    1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 668  Solved: 337[Submit][Statu ...

  10. 修改sphinx最大输出记录数

    修改sphinx最大输出记录数 归纳如下: Sphinx的查询默认最大记录数是:1000,而我们想更改这个数值.就需要更改三个地方. 1是更改sphinx.conf配置文件的:max_matches ...