Description

给您一颗树,每个节点有个初始值。

现在支持以下两种操作:

  1. C i x(0<=x<2^31) 表示将i节点的值改为x。
  2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

解题报告:

用时:1h20min,3WA

简单题,对每一种颜色建一棵树链剖分的数组,可以持久化一下,动态加点,暴力搞搞即可

空间时间复杂度:\(O((n+m)logn)\)

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #include <cmath>
  7. #define RG register
  8. #define il inline
  9. #define iter iterator
  10. #define Max(a,b) ((a)>(b)?(a):(b))
  11. #define Min(a,b) ((a)<(b)?(a):(b))
  12. using namespace std;
  13. const int N=100005;
  14. int n,m,head[N],num=0,to[N<<1],nxt[N<<1],col[N],id[N],DFN=0,b[N<<2],sum=0;
  15. struct question{int flag,x,y,z;}q[N<<1];
  16. void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
  17. int dep[N],top[N],fa[N],sz[N],son[N],tot;char s[3];
  18. void dfs1(int x){
  19. int u;sz[x]=1;
  20. for(int i=head[x];i;i=nxt[i]){
  21. u=to[i];if(dep[u])continue;
  22. dep[u]=dep[x]+1;fa[u]=x;
  23. dfs1(u);
  24. sz[x]+=sz[u];
  25. if(sz[u]>sz[son[x]])son[x]=u;
  26. }
  27. }
  28. void dfs2(int x,int tp){
  29. top[x]=tp;id[x]=++DFN;
  30. if(son[x])dfs2(son[x],tp);
  31. for(int i=head[x];i;i=nxt[i])
  32. if(to[i]!=son[x] && to[i]!=fa[x])dfs2(to[i],to[i]);
  33. }
  34. int totnode=0,root[N<<2];
  35. struct node{int l,r,s;}t[N*160];
  36. void updata(int &rt,int last,int l,int r,int sa,int to){
  37. rt=++totnode;t[rt]=t[last];
  38. if(l==r){t[rt].s+=to;return ;}
  39. int mid=(l+r)>>1;
  40. if(sa>mid)updata(t[rt].r,t[last].r,mid+1,r,sa,to);
  41. else updata(t[rt].l,t[last].l,l,mid,sa,to);
  42. t[rt].s=t[t[rt].l].s+t[t[rt].r].s;
  43. }
  44. int query(int rt,int l,int r,int sa,int se){
  45. if(l>se || r<sa)return 0;
  46. if(sa<=l && r<=se)return t[rt].s;
  47. int mid=(l+r)>>1;
  48. return query(t[rt].l,l,mid,sa,se)+query(t[rt].r,mid+1,r,sa,se);
  49. }
  50. int solve(int x,int y,int co){
  51. int ret=0;
  52. while(top[x]!=top[y]){
  53. if(dep[top[x]]<dep[top[y]])swap(x,y);
  54. ret+=query(root[co],1,n,id[top[x]],id[x]);
  55. x=fa[top[x]];
  56. }
  57. if(id[x]>id[y])swap(x,y);
  58. ret+=query(root[co],1,n,id[x],id[y]);
  59. return ret;
  60. }
  61. void work()
  62. {
  63. int x,y;
  64. scanf("%d%d",&n,&m);
  65. for(int i=1;i<=n;i++)scanf("%d",&col[i]),b[++sum]=col[i];
  66. for(int i=1;i<n;i++){
  67. scanf("%d%d",&x,&y);
  68. link(x,y);link(y,x);
  69. }
  70. dep[1]=1;dfs1(1);dfs2(1,1);
  71. for(int i=1;i<=m;i++){
  72. scanf("%s%d%d",s,&q[i].x,&q[i].y);
  73. if(s[0]=='C')q[i].flag=0,b[++sum]=q[i].y;
  74. else scanf("%d",&q[i].z),q[i].flag=1,b[++sum]=q[i].z;
  75. }
  76. sort(b+1,b+sum+1);
  77. tot=unique(b+1,b+sum+1)-b-1;
  78. for(int i=1;i<=n;i++){
  79. col[i]=lower_bound(b+1,b+tot+1,col[i])-b;
  80. updata(root[col[i]],root[col[i]],1,n,id[i],1);
  81. }
  82. for(int i=1;i<=m;i++){
  83. x=q[i].x;y=q[i].y;
  84. if(q[i].flag==0){
  85. y=lower_bound(b+1,b+tot+1,y)-b;
  86. updata(root[col[x]],root[col[x]],1,n,id[x],-1);
  87. updata(root[y],root[y],1,n,id[x],1);
  88. col[x]=y;
  89. }
  90. else{
  91. q[i].z=lower_bound(b+1,b+tot+1,q[i].z)-b;
  92. printf("%d\n",solve(x,y,q[i].z));
  93. }
  94. }
  95. }
  96. int main()
  97. {
  98. work();
  99. return 0;
  100. }

4999: This Problem Is Too Simple!的更多相关文章

  1. bzoj 4999: This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  2. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

  3. 【BZOJ4999】This Problem Is Too Simple!(线段树)

    [BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...

  4. 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA

    [BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2 ...

  5. [BZOJ 4999]This Problem Is Too Simple!

    [BZOJ 4999]This Problem Is Too Simple! 题目 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将 ...

  6. bzoj4999 This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  7. 2019.03.09 bzoj4999: This Problem Is Too Simple!(树链剖分+线段树动态开点)

    传送门 题意:给一颗树,每个节点有个初始值,要求支持将i节点的值改为x或询问i节点到j节点的路径上有多少个值为x的节点. 思路: 考虑对每种颜色动态开点,然后用树剖+线段树维护就完了. 代码: #in ...

  8. BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树

    题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...

  9. BZOJ4999:This Problem Is Too Simple!(DFS序&树上差分&线段树动态开点:区间修改单点查询)

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

随机推荐

  1. Beta冲刺Day7

    项目进展 李明皇 今天解决的进度 部分数据传递和使用逻辑测试 林翔 今天解决的进度 服务器端查看个人发布的action,修改已发布消息状态的action,仍在尝试使用第三方云存储功能保存图片 孙敏铭 ...

  2. 【iOS】swift init构造器

    这几天在使用 Swift 重写原来的一个运动社交应用 SportJoin. 为什么要重写呢? 首先因为实在找不到设计师给我作图; 其次, 我也闲不下来, 想找一些项目做, 所以只好将原来的代码重写了. ...

  3. 【iOS】Swift ?和 !(详解)

    Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值, 也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化 .如果在使用变量之前不进行初始化就会报错: [ ...

  4. Django 测试驱动开发

    第一章 1.编写functional_tests.py from selenium import webdriver browser = webdriver.Firefox() browser.get ...

  5. 从PRISM开始学WPF(六)MVVM(二)Command?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  6. dede观看总结自己总结

    知识点一:{dede:arclist channelid="18" addfields="language,pfz" limit="0,5" ...

  7. JavaScript AJAX实例

    原生JS实现AJAX: // method : 请求方式 POST/GET; // url: 如果为GET方式的话url里面要带参数 // obj: 准备好的容器,方便储存拿到的数据 function ...

  8. python利用递归函数输出嵌套列表的每个元素

    1.先用 for 循环取. for item in l: if isinstance(item ,list): for newitem in item: print(newitem) else: pr ...

  9. vSphere Client 搭建Windows server 2008 r2 服务器指南

    下载准备 下载并安装vSphere Client 链接:https://pan.baidu.com/s/1v0IrGrMjpA2FGeqagaJN-g 密码:zzd1 下载Windows server ...

  10. 新概念英语(1-29)Come in, Amy.

    How must Amy clean the floor? A:Come in, Amy. Shut the door, please. This bedroom's very untidy. B:W ...