好吧这其实应该不是树剖...

因为只要求子树就够了,dfs就好了

大概就是记录一个全局根root

多画几幅图会发现修改时x,y以root为根时的lca为以1为根时的lca(x,y),lca(root,x),lca(root,y)中深度最大的一个

然后就可以做了

然后分类讨论当前更改操作节点x(更新即LCA(x,y),询问则就是x)和root的关系:

(接下来有关操作都以1为根)

1.x=root: 即询问/修改整颗树的权值和

2.root不在x的子树内:这样的话这里x的子树是没有被影响到的,直接修改就好了

3.root在x的子树内:画图发现(不会证明)从root到x的路径上的最后一个节点(不包括root和x)的子树是不要修改的,其他都要修改,这里用一下容斥就好了

维护区间和用线段树,lca用倍增(因为后面倍增还可以用来求路径,方便)

大概就好了

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define writeln(x) write(x),puts("")
  4. using namespace std;
  5. inline int read(){
  6. int ans=,f=;char chr=getchar();
  7. while(!isdigit(chr)){if(chr=='-') f=-;chr=getchar();}
  8. while(isdigit(chr)){ans=(ans<<)+(ans<<)+chr-;chr=getchar();}
  9. return ans*f;
  10. }void write(int x){
  11. if(x<) putchar('-'),x=-x;
  12. if(x>) write(x/);
  13. putchar(x%+'');
  14. }const int M = 1e5+;
  15. int head[M],ver[M<<],nxt[M<<],tot,n,m,dfn[M],b[M],a[M],fa[M][],sz[M],T,dep[M],s[M<<],lz[M<<],root,x,y,z,t,ans;
  16. inline void add(int x,int y){ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
  17. void dfs(int x,int f){
  18. dfn[x]=++T,fa[x][]=f,b[dfn[x]]=a[x],dep[x]=dep[f]+,sz[x]=;
  19. for(int i=;(<<i)<=dep[x];i++)fa[x][i]=fa[fa[x][i-]][i-];
  20. for(int i=head[x];i;i=nxt[i]){
  21. if(ver[i]==f) continue;
  22. dfs(ver[i],x);
  23. sz[x]+=sz[ver[i]];
  24. }
  25. }
  26. int LCA(int x,int y){
  27. if(dep[x]<dep[y]) swap(x,y);
  28. for(int i=;i>=;i--)if(dep[x]-(<<i)>=dep[y]) x=fa[x][i];
  29. if(x==y) return x;
  30. for(int i=;i>=;i--)
  31. if(fa[x][i]!=fa[y][i])
  32. x=fa[x][i],y=fa[y][i];
  33. return fa[x][];
  34. }
  35. #define ls (i<<1)
  36. #define rs (i<<1|1)
  37. #define mid (l+r>>1)
  38. inline void Push_Up(int i){s[i]=s[ls]+s[rs];}
  39. inline void Push_Down(int i,int l,int r){
  40. if(!lz[i]) return;
  41. s[ls]+=lz[i]*(mid-l+);
  42. s[rs]+=lz[i]*(r-mid);
  43. lz[ls]+=lz[i],lz[rs]+=lz[i];
  44. lz[i]=;
  45. }
  46. void Build(int i,int l,int r){
  47. if(l==r) return (void)(s[i]=b[l]);
  48. Build(ls,l,mid),Build(rs,mid+,r);
  49. Push_Up(i);
  50. }
  51. void Update(int i,int l,int r,int ql,int qr,int x){
  52. if(ql<=l&&r<=qr)return (void)(s[i]+=(r-l+)*x,lz[i]+=x);
  53. Push_Down(i,l,r);
  54. if(ql<=mid) Update(ls,l,mid,ql,qr,x);
  55. if(qr>mid) Update(rs,mid+,r,ql,qr,x);
  56. Push_Up(i);
  57. }
  58. int Query(int i,int l,int r,int ql,int qr){
  59. if(ql<=l&&r<=qr) return s[i];
  60. int ans=;Push_Down(i,l,r);
  61. if(ql<=mid) ans+=Query(ls,l,mid,ql,qr);
  62. if(qr>mid) ans+=Query(rs,mid+,r,ql,qr);
  63. return ans;
  64. }
  65. inline int Get_Point(int x,int y){
  66. int l1=LCA(x,y),l2=LCA(x,root),l3=LCA(y,root);
  67. if(dep[l1]<dep[l2]) swap(l1,l2);
  68. if(dep[l1]<dep[l3]) swap(l1,l3);
  69. return l1;
  70. }
  71. inline Get(int x,int d){for(int i=;i>=;i--) if((<<i)&d) x=fa[x][i];return x;}
  72. inline void Solve_1(){
  73. x=read(),y=read(),z=read();
  74. t=Get_Point(x,y);
  75. if(t==root) return (void)(Update(,,n,,n,z));
  76. if(dfn[t]>dfn[root]||dfn[t]+sz[t]-<dfn[root]) return (void)(Update(,,n,dfn[t],dfn[t]+sz[t]-,z));
  77. int tmp=Get(root,dep[root]-dep[t]-);
  78. Update(,,n,,n,z);Update(,,n,dfn[tmp],dfn[tmp]+sz[tmp]-,-z);
  79. }
  80. inline void Solve_2(){
  81. x=read();
  82. if(x==root) return (void)(writeln(Query(,,n,,n)));
  83. if(dfn[x]>dfn[root]||dfn[x]+sz[x]-<dfn[root]) return (void)(writeln(Query(,,n,dfn[x],dfn[x]+sz[x]-)));
  84. int tmp=Get(root,dep[root]-dep[x]-);
  85. ans=Query(,,n,,n);ans-=Query(,,n,dfn[tmp],dfn[tmp]+sz[tmp]-);
  86. writeln(ans);
  87. }
  88. signed main(){
  89. n=read(),m=read();
  90. for(int i=;i<=n;i++) a[i]=read();
  91. for(int i=;i<n;i++)x=read(),y=read(),add(x,y),add(y,x);
  92. dfs(,);Build(,,n);root=;
  93. while(m--){
  94. int opt=read();
  95. if(opt==) root=read();
  96. if(opt==) Solve_1();
  97. if(opt==) Solve_2();
  98. }
  99. return ;
  100. }

【树剖】CF916E Jamie and Tree的更多相关文章

  1. CF916E Jamie and Tree

    CF916E Jamie and Tree 题意翻译 有一棵n个节点的有根树,标号为1-n,你需要维护以下三种操作 1.给定一个点v,将整颗树的根变为v 2.给定两个点u, v,将lca(u, v)所 ...

  2. CF916E Jamie and Tree 解题报告

    CF916E Jamie and Tree 题意翻译 有一棵\(n\)个节点的有根树,标号为\(1-n\),你需要维护一下三种操作 1.给定一个点\(v\),将整颗树的根变为\(v\) 2.给定两个点 ...

  3. 题解 [CF916E] Jamie and Tree

    题面 解析 这题考试时刚了四个小时. 结果还是爆零了 主要就是因为\(lca\)找伪了. 我们先考虑没有操作1,那就是裸的线段树. 在换了根以后,主要就是\(lca\)不好找(分类讨论伪了). 我们将 ...

  4. SPOJ Query on a tree III (树剖(dfs序)+主席树 || Splay等平衡树)(询问点)

    You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose ...

  5. SPOJ375Query on a tree I(树剖+线段树)(询问边)

    ιYou are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  6. POJ3237 Tree(树剖+线段树+lazy标记)

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

  7. codeforces 916E Jamie and Tree dfs序列化+线段树+LCA

    E. Jamie and Tree time limit per test 2.5 seconds memory limit per test 256 megabytes input standard ...

  8. SP375 QTREE - Query on a tree (树剖)

    题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...

  9. 2019.01.19 codeforces343D.Water Tree(树剖+ODT)

    传送门 ODTODTODT板子题. 支持子树01覆盖,路径01覆盖,询问一个点的值. 思路:当然可以用树剖+线段树,不过树剖+ODTODTODT也可以很好的水过去. 注意修改路径时每次跳重链都要修改. ...

随机推荐

  1. NX二次开发-UFUN获得当前图纸页有多少个视图UF_DRAW_ask_num_views

    #include <uf.h> #include <uf_draw.h> #include <uf_ui.h> UF_initialize(); //获得当前图纸页 ...

  2. 使用RAS+AES对接口数据加解密

    在实际开发中,会遇到两个系统之间传输数据,为了对传输的数据进行保护,需要发送方对接口数据进行加密,接收方对数据解密. 对数据加密,采用RSA+AES双重加密,是数据更加安全. 使用前提: 如果客户端本 ...

  3. nc命令官方Demo实例

    nc命令可用于发送任务tcp/udp连接和监听. 官方描述的主要功能包括: simple TCP proxies shell-script based HTTP clients and servers ...

  4. Centos6.5安装ruby2.2.3

    一.安装库 Yum install –y gcc* openssl* wget 二.安装ruby wget https://cache.ruby-lang.org/pub/ruby/2.2/ruby- ...

  5. java: java中的 getInstance() 的理解

    原文地址:https://blog.csdn.net/qq_26293573/article/details/78184844 在单例模式下使用 . 单例模式:所谓单例模式就是一个类有且只有一个实例, ...

  6. Lombok 常用注解

    Lombok Lombok 能以简单的注解形式来简化 java 代码,提高开发人员的开发效率.例如开发中经常需要写的 javaBean,都需要花时间去添加相应的 getter/setter,也许还要去 ...

  7. 20140309 C++ using 野指针 返回变量首地址

    1.C++中的using:http://blog.sina.com.cn/s/blog_61e904fd0100nuk3.html 使用using恢复.改变被继承类中的访问权限 2.野指针,没有指向的 ...

  8. xwiki系统 知识库 xwiki

    1.下载tomcat tar  -zxvf  apache-tomcat-8.0.14.tar.gz mv apache-tomcat-8.0.14 tomcat-xwiki-8.0 2.下载xwik ...

  9. Spring注解基础学习总结

    1.依赖注入注解: @Component:Bean注入到Spring容器组件(通用) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE):Bean作用域( ...

  10. IDEA被删除的模块在编译时会再次出现

    工程根目录下.idea文件->compiler.xml,删除多余的model,workspace.xml->删除带有无用的target标签