1. [ZJOI2008]树的统计Count

    ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比

    时间限制:5 s 内存限制:162 MB

    【题目描述】

    一棵树上有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本身

    【输入格式】

    输入的第一行为一个整数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之间。

    【输出格式】

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

    【样例输入】

    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

    【样例输出】

    4

    1

    2

    2

    10

    6

    5

    6

    5

    16
  1. /*
  2. 树链剖分模板题.
  3. 套线段树
  4. 单点修改,区间查询sum,max.
  5. */
  6. #include<iostream>
  7. #include<cstdio>
  8. #define MAXN 300001
  9. using namespace std;
  10. int pos[MAXN],tot,son[MAXN],top[MAXN],size[MAXN],deep[MAXN],fa[MAXN];
  11. int head[MAXN],a[MAXN],n,m,cut,maxsize;
  12. struct data{int l,r,sum,lc,rc,max;}tree[MAXN*4];
  13. struct edge{int v,next;}e[MAXN*2];
  14. int read()
  15. {
  16. int x=0,f=1;char ch=getchar();
  17. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  18. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  19. return x*f;
  20. }
  21. void add(int u,int v)
  22. {
  23. e[++cut].v=v;
  24. e[cut].next=head[u];
  25. head[u]=cut;
  26. }
  27. void build(int l,int r)
  28. {
  29. int k=++cut;
  30. tree[k].l=l,tree[k].r=r;
  31. if(l==r) {tree[k].sum=tree[k].max=0;return ;}
  32. int mid=(l+r)>>1;
  33. tree[k].lc=cut+1;build(l,mid);
  34. tree[k].rc=cut+1;build(mid+1,r);
  35. }
  36. void dfs1(int u)
  37. {
  38. size[u]=1;
  39. for(int i=head[u];i;i=e[i].next)
  40. {
  41. int v=e[i].v;
  42. if(fa[u]==v) continue;
  43. deep[v]=deep[u]+1;
  44. fa[v]=u;dfs1(v);
  45. size[u]+=size[v];
  46. }
  47. return ;
  48. }
  49. void dfs2(int u,int top1)
  50. {
  51. int k=0;maxsize++;
  52. pos[u]=maxsize;top[u]=top1;
  53. for(int i=head[u];i;i=e[i].next)
  54. {
  55. int v=e[i].v;
  56. if(deep[v]>deep[u]&&size[v]>size[k]) k=v;
  57. }
  58. if(!k) return ;
  59. dfs2(k,top1);
  60. for(int i=head[u];i;i=e[i].next)
  61. if(deep[e[i].v]>deep[u]&&e[i].v!=k) dfs2(e[i].v,e[i].v);
  62. return ;
  63. }
  64. void change(int k,int x,int val)
  65. {
  66. if(tree[k].l==tree[k].r) {tree[k].sum=tree[k].max=val;return ;}
  67. int mid=(tree[k].l+tree[k].r)>>1;
  68. if(x<=mid) change(tree[k].lc,x,val);
  69. else if(x>mid) change(tree[k].rc,x,val);
  70. tree[k].sum=tree[tree[k].lc].sum+tree[tree[k].rc].sum;
  71. tree[k].max=max(tree[tree[k].lc].max,tree[tree[k].rc].max);
  72. }
  73. int querysum(int k,int l,int r)
  74. {
  75. if(l<=tree[k].l&&tree[k].r<=r) return tree[k].sum;
  76. int mid=(tree[k].l+tree[k].r)>>1,total=0;
  77. if(l<=mid) total+=querysum(tree[k].lc,l,r);
  78. if(r>mid) total+=querysum(tree[k].rc,l,r);
  79. return total;
  80. }
  81. int querymax(int k,int l,int r)
  82. {
  83. if(l<=tree[k].l&&tree[k].r<=r) return tree[k].max;
  84. int mid=(tree[k].l+tree[k].r)>>1,total=-1e9;
  85. if(l<=mid) total=max(total,querymax(tree[k].lc,l,r));
  86. if(r>mid) total=max(total,querymax(tree[k].rc,l,r));
  87. return total;
  88. }
  89. int slovesum(int x,int y)
  90. {
  91. int ans=0;
  92. while(top[x]!=top[y])
  93. {
  94. if(deep[top[x]]<deep[top[y]]) swap(x,y);
  95. ans+=querysum(1,pos[top[x]],pos[x]);
  96. x=fa[top[x]];
  97. }
  98. if(pos[x]>pos[y]) swap(x,y);
  99. ans+=querysum(1,pos[x],pos[y]);
  100. return ans;
  101. }
  102. int slovemax(int x,int y)
  103. {
  104. int ans=-1e9;
  105. while(top[x]!=top[y])
  106. {
  107. if(deep[top[x]]<deep[top[y]]) swap(x,y);
  108. ans=max(ans,querymax(1,pos[top[x]],pos[x]));
  109. x=fa[top[x]];
  110. }
  111. if(pos[x]>pos[y]) swap(x,y);
  112. ans=max(ans,querymax(1,pos[x],pos[y]));
  113. return ans;
  114. }
  115. int main()
  116. {
  117. freopen("bzoj_1036.in","r",stdin);
  118. freopen("bzoj_1036.out","w",stdout);
  119. int x,y;
  120. n=read();
  121. for(int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
  122. for(int i=1;i<=n;i++) a[i]=read();
  123. dfs1(1),dfs2(1,1);
  124. cut=0;build(1,maxsize);
  125. for(int i=1;i<=n;i++) change(1,pos[i],a[i]);
  126. m=read();char ch[11];
  127. while(m--)
  128. {
  129. scanf("%s",ch);
  130. scanf("%d%d",&x,&y);
  131. if(ch[0]=='C') a[x]=y,change(1,pos[x],y);
  132. else {
  133. if(ch[1]=='M') printf("%d\n",slovemax(x,y));
  134. else printf("%d\n",slovesum(x,y));
  135. }
  136. }
  137. return 0;
  138. }
  1. /*
  2. LCT.
  3. */
  4. #include<iostream>
  5. #include<cstdio>
  6. #define MAXN 30001
  7. #define INF 1e9
  8. using namespace std;
  9. struct data{int x,y;}s[MAXN];
  10. int n,m,a[MAXN],tree[MAXN][2],max1[MAXN],st[MAXN],sum[MAXN],fa[MAXN],rev[MAXN];
  11. int read()
  12. {
  13. int x=0,f=1;char ch=getchar();
  14. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  15. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  16. return x*f;
  17. }
  18. bool isroot(int x)
  19. {
  20. return tree[fa[x]][0]!=x&&tree[fa[x]][1]!=x;
  21. }
  22. void pushdown(int x)
  23. {
  24. rev[tree[x][0]]^=1,rev[tree[x][1]]^=1;
  25. rev[x]^=1;swap(tree[x][0],tree[x][1]);
  26. return ;
  27. }
  28. void updata(int k)
  29. {
  30. sum[k]=a[k]+sum[tree[k][0]]+sum[tree[k][1]];
  31. max1[k]=max(a[k],max(max1[tree[k][0]],max1[tree[k][1]]));
  32. return ;
  33. }
  34. void rotate(int x)
  35. {
  36. int y=fa[x],z=fa[y],l,r;
  37. if(tree[y][1]==x) l=1;else l=0;r=l^1;
  38. if(!isroot(y))
  39. {
  40. if(tree[z][0]==y) tree[z][0]=x;
  41. else tree[z][1]=x;
  42. }
  43. fa[x]=z,fa[y]=x;fa[tree[x][r]]=y;
  44. tree[y][l]=tree[x][r],tree[x][r]=y;
  45. updata(y),updata(x);
  46. return ;
  47. }
  48. void splay(int x)
  49. {
  50. int top=0,y,z;st[++top]=x;
  51. for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
  52. for(int i=top;i;i--) if(rev[st[i]]) pushdown(st[i]);
  53. while(!isroot(x))
  54. {
  55. y=fa[x],z=fa[y];
  56. if(!isroot(y))
  57. {
  58. if((tree[z][0]==y)^(tree[y][0]==x)) rotate(x);
  59. else rotate(y);
  60. }
  61. rotate(x);
  62. }
  63. return ;
  64. }
  65. void access(int x)
  66. {
  67. int t=0;
  68. while(x) splay(x),tree[x][1]=t,updata(x),t=x,x=fa[x];
  69. return ;
  70. }
  71. void makeroot(int x)
  72. {
  73. access(x),splay(x),rev[x]^=1;
  74. return ;
  75. }
  76. void join(int x,int y)
  77. {
  78. makeroot(x),fa[x]=y,splay(x);
  79. return ;
  80. }
  81. void slovechange(int x,int y)
  82. {
  83. splay(x),a[x]=y,updata(x);
  84. return ;
  85. }
  86. void slovequery(int x,int y)//先转x,再转y.
  87. {
  88. makeroot(x),access(y),splay(y);
  89. return ;
  90. }
  91. int main()
  92. {
  93. freopen("bzoj_1036.in","r",stdin);
  94. freopen("bzoj_1036.out","w",stdout);
  95. int x,y;
  96. n=read();max1[0]=-INF;
  97. for(int i=1;i<=n-1;i++) s[i].x=read(),s[i].y=read();
  98. for(int i=1;i<=n;i++) a[i]=read(),sum[i]=max1[i]=a[i];
  99. for(int i=1;i<=n-1;i++) join(s[i].x,s[i].y);
  100. m=read();char ch[10];
  101. while(m--)
  102. {
  103. scanf("%s",ch);x=read(),y=read();
  104. if(ch[0]=='C') slovechange(x,y);
  105. else
  106. {
  107. slovequery(x,y);
  108. if(ch[1]=='M') printf("%d\n",max1[y]);
  109. else printf("%d\n",sum[y]);
  110. }
  111. }
  112. return 0;
  113. }

Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)的更多相关文章

  1. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  2. 【bzoj1036】树的统计[ZJOI2008]树链剖分+线段树

    题目传送门:1036: [ZJOI2008]树的统计Count 这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. Photon Server初识(六) --- 客户端与服务端消息传递

    前一章客户端与服务端连接成功,现在需要前后端进行数据传递. 一.前端发送消息.在项目Scripts目录中新建脚本 TestSer.cs.并挂载到相机上 二.客户端发送数据给服务端.编辑客户端代码 Te ...

  2. Devexpress xaf针对某个用户登录后在面板中设置导航无效的解决方法

    Devexpress xaf框架生成的项目默认情况下导航栏是显示在左侧,有时候我们用某个账户登录后,发现导航栏无法显示在左侧,操作十分不方便.我们可以去数据库删除当前登录用户的自定义布局 解决方法如下 ...

  3. 少儿编程Scratch第三讲:宇宙大战.枪战游戏

    小朋友这周的表现还算不错.周末多数时间都由我陪(bi)着(zhe)做课本上的数学题,后来还学了英语.任重道远啊,语数外都还得加强,还远不到自己就能取得好成绩的阶段. 上周说好这周要做一个发射炮弹的游戏 ...

  4. python基础知识0-1

    绝对值:abs age = -19 age.__abs__() 19 相加: add age.__add__() 与运算:and age.__add__() 比较两个数大小:cmp age._cmp_ ...

  5. 怎样发出一个HTTP请求

    需要使用 xhr.send(); 参数为请求数据体, 如果没有就传入null, 一般来说, GET请求是不用传参的, POST就视情况而定, 理论上所有GET请求都可以改为POST, 反之则不行. v ...

  6. uni-app使用Canvas绘图

    最近公司项目在用uni-app做小程序商城,其中商品和个人需要生成图片海报,经过摸索记录后将一些重点记录下来.这里有两种方式来生成 1.后台控制生成 2.前端用canvas合成图片 这里我们只讲使用c ...

  7. 【转】CSS之Background-Position left right center top bottom属性

    background-position:left top; 背景图片的左上角和容器(container)的左上角对齐,超出的部分隐藏. 等同于 background-position:0,0; 也等同 ...

  8. 页面加载完毕后调用js方法进行布局操控 已实验

    页面加载完毕后调用js方法进行布局操控 已实验 $(function(){ var check1 = $("[id$=SMS]").is(':checked'); var bl=$ ...

  9. 2. An Array of Sequences

    1. Overview of Built-In Sequences Container sequences: list, tuple, and collections.deque can hold i ...

  10. Ubuntu系统--安装官方flash插件包的方法

    浏览器安装官方install_flash_player_npapi_linux.x86_64.tar.gz插件包的方法 第一步:下载安装包. adobe flash player的官方下载instal ...