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

因为只要求子树就够了,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用倍增(因为后面倍增还可以用来求路径,方便)

大概就好了

 #include<bits/stdc++.h>
#define int long long
#define writeln(x) write(x),puts("")
using namespace std;
inline int read(){
int ans=,f=;char chr=getchar();
while(!isdigit(chr)){if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)){ans=(ans<<)+(ans<<)+chr-;chr=getchar();}
return ans*f;
}void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}const int M = 1e5+;
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;
inline void add(int x,int y){ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
void dfs(int x,int f){
dfn[x]=++T,fa[x][]=f,b[dfn[x]]=a[x],dep[x]=dep[f]+,sz[x]=;
for(int i=;(<<i)<=dep[x];i++)fa[x][i]=fa[fa[x][i-]][i-];
for(int i=head[x];i;i=nxt[i]){
if(ver[i]==f) continue;
dfs(ver[i],x);
sz[x]+=sz[ver[i]];
}
}
int LCA(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)if(dep[x]-(<<i)>=dep[y]) x=fa[x][i];
if(x==y) return x;
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
}
#define ls (i<<1)
#define rs (i<<1|1)
#define mid (l+r>>1)
inline void Push_Up(int i){s[i]=s[ls]+s[rs];}
inline void Push_Down(int i,int l,int r){
if(!lz[i]) return;
s[ls]+=lz[i]*(mid-l+);
s[rs]+=lz[i]*(r-mid);
lz[ls]+=lz[i],lz[rs]+=lz[i];
lz[i]=;
}
void Build(int i,int l,int r){
if(l==r) return (void)(s[i]=b[l]);
Build(ls,l,mid),Build(rs,mid+,r);
Push_Up(i);
}
void Update(int i,int l,int r,int ql,int qr,int x){
if(ql<=l&&r<=qr)return (void)(s[i]+=(r-l+)*x,lz[i]+=x);
Push_Down(i,l,r);
if(ql<=mid) Update(ls,l,mid,ql,qr,x);
if(qr>mid) Update(rs,mid+,r,ql,qr,x);
Push_Up(i);
}
int Query(int i,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return s[i];
int ans=;Push_Down(i,l,r);
if(ql<=mid) ans+=Query(ls,l,mid,ql,qr);
if(qr>mid) ans+=Query(rs,mid+,r,ql,qr);
return ans;
}
inline int Get_Point(int x,int y){
int l1=LCA(x,y),l2=LCA(x,root),l3=LCA(y,root);
if(dep[l1]<dep[l2]) swap(l1,l2);
if(dep[l1]<dep[l3]) swap(l1,l3);
return l1;
}
inline Get(int x,int d){for(int i=;i>=;i--) if((<<i)&d) x=fa[x][i];return x;}
inline void Solve_1(){
x=read(),y=read(),z=read();
t=Get_Point(x,y);
if(t==root) return (void)(Update(,,n,,n,z));
if(dfn[t]>dfn[root]||dfn[t]+sz[t]-<dfn[root]) return (void)(Update(,,n,dfn[t],dfn[t]+sz[t]-,z));
int tmp=Get(root,dep[root]-dep[t]-);
Update(,,n,,n,z);Update(,,n,dfn[tmp],dfn[tmp]+sz[tmp]-,-z);
}
inline void Solve_2(){
x=read();
if(x==root) return (void)(writeln(Query(,,n,,n)));
if(dfn[x]>dfn[root]||dfn[x]+sz[x]-<dfn[root]) return (void)(writeln(Query(,,n,dfn[x],dfn[x]+sz[x]-)));
int tmp=Get(root,dep[root]-dep[x]-);
ans=Query(,,n,,n);ans-=Query(,,n,dfn[tmp],dfn[tmp]+sz[tmp]-);
writeln(ans);
}
signed main(){
n=read(),m=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<n;i++)x=read(),y=read(),add(x,y),add(y,x);
dfs(,);Build(,,n);root=;
while(m--){
int opt=read();
if(opt==) root=read();
if(opt==) Solve_1();
if(opt==) Solve_2();
}
return ;
}

最新文章

  1. 关于httpd服务的安装、配置
  2. CentOS 7 64位的安装流程
  3. html中使用js实现内容过长时部分
  4. django的ajax对应前端的瀑布流方法
  5. FMS Camera对象设置说明
  6. Zero Requiem
  7. Android Studio设备背景色
  8. 关于location
  9. OPENFILER记下,有空再玩之,ISCSI,以后网络起来了,速度还是应该可以的
  10. VC使用#定义方便控制版本号的宏
  11. 设置cmd的codepage的方法
  12. C++ : 类型的别名和对象的别名
  13. Java. Warning – Build path specifies execution environment J2SE-1.5
  14. 双刃剑MongoDB的学习和避坑
  15. D - Nature Reserve(cf514,div2)
  16. ArcGis Python脚本——批量删除字段
  17. java_工厂模式
  18. CSDN 博客 美化 个性化
  19. QuickHit 项目
  20. 【Python】unittest-4

热门文章

  1. RDBMS关系型数据库与HBase的对比
  2. NOIp2018集训test-9-5(pm)
  3. NX二次开发-获取尺寸的附加文本UF_DRF_ask_appended_text
  4. ftp和ssh登录缓慢的解决办法
  5. iOS开发UIEvent事件简介
  6. python中面向对象
  7. 2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型
  8. Docker学习のDocker的简单应用
  9. Haar分类器方法
  10. WIN10安装CUDA10 cuDNN