思路:

先搞出来每个点的DFS序 (要有入栈和出栈两种状态的)

处理出来 线段树区间有多少入栈的和多少出栈的

加区间的时候就加(入-出)*wei

查前缀和

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 200050
#define int long long
int n,m,Wei[N],v[N],first[N],next[N],tot,start[N],end[N],cnt;
int xx,yy,ww,op,tree[N*20],mark[N*20],marka[N*20],vv[N];
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void dfs(int x,int fa){
start[x]=++cnt;vv[cnt]=1;
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa)
dfs(v[i],x);
end[x]=++cnt;vv[cnt]=-1;
}
void push_down(int pos){
int lson=pos<<1,rson=pos<<1|1;
tree[lson]+=mark[lson]*marka[pos];
tree[rson]+=mark[rson]*marka[pos];
marka[lson]+=marka[pos];
marka[rson]+=marka[pos];
marka[pos]=0;
}
void build(int l,int r,int pos){
if(l==r){mark[pos]=vv[l];return;}
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
build(l,mid,lson),build(mid+1,r,rson);
mark[pos]=mark[lson]+mark[rson];
}
void insert(int l,int r,int pos,int wei,int x){
if(l==r){tree[pos]+=wei;return;}
if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid<x)insert(mid+1,r,rson,wei,x);
else insert(l,mid,lson,wei,x);
tree[pos]=tree[lson]+tree[rson];
}
int query(int l,int r,int pos,int x){
if(r<=x){return tree[pos];}
if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid>=x)return query(l,mid,lson,x);
else return query(l,mid,lson,x)+query(mid+1,r,rson,x);
}
void Change(int l,int r,int pos){
if(l>=xx&&r<=yy){
marka[pos]+=ww;
tree[pos]+=ww*mark[pos];
return;
}
if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid<xx)Change(mid+1,r,rson);
else if(mid>=yy)Change(l,mid,lson);
else Change(l,mid,lson),Change(mid+1,r,rson);
tree[pos]=tree[lson]+tree[rson];
}
signed main(){
memset(first,-1,sizeof(first));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&Wei[i]);
for(int i=1;i<n;i++)
scanf("%lld%lld",&xx,&yy),add(xx,yy),add(yy,xx);
dfs(1,-1);
build(1,cnt,1);
for(int i=1;i<=n;i++)
insert(1,cnt,1,Wei[i],start[i]),insert(1,cnt,1,-Wei[i],end[i]);
for(int i=1;i<=m;i++){
scanf("%lld",&op);
if(op==1){
scanf("%lld%lld",&xx,&ww);
insert(1,cnt,1,ww,start[xx]);
insert(1,cnt,1,-ww,end[xx]);
}
else if(op==2){
scanf("%lld%lld",&xx,&ww);
yy=end[xx],xx=start[xx];
Change(1,cnt,1);
}
else if(op==3){
scanf("%lld",&xx);
printf("%lld\n",query(1,cnt,1,start[xx]));
}
}
}

最新文章

  1. Module模式
  2. Java 类中各成分加载顺序 和 内存中的存放位置
  3. HDU 3400 Line belt【三分套三分】
  4. Qt_Window@Qt Command Prompt从命令行创建工程
  5. Word中字体背景有白块咋办
  6. numa对MySQL多实例性能影响
  7. Storm Esper
  8. The Accumulation of Capital
  9. 重温《STL源码剖析》笔记 第二章
  10. 关于Android Studio 代理
  11. DynamicEnumUtil 动态添加枚举类的枚举值
  12. mysql主从同步(2)-问题梳理
  13. Centos7下安装python3
  14. react 脚手架--create-react-app
  15. jenkins之从0到1利用Git和Ant插件打war包并自动部署到tomcat(第一话):初次启动jenkins,输入给定密码后登录失败问题解决
  16. centos 6 下KVM 安装学习之旅
  17. PHP调用mysql函数整理
  18. .net中单选按钮RadioButton,RadioButtonList 以及纯Html中radio的用法实例?
  19. &gt; Manifest merger failed with multiple errors, see logs -- Android Studio问题汇总
  20. java Properties的用法

热门文章

  1. eclipse/myeclipse中js/java的自动提示只有4个字符怎么解决
  2. TODOList 多线程交互、RCP、事物控制、数据倾斜、HBase数据同步性
  3. Android Camera子系统之Linux C应用开发人员View
  4. [ xml ] [ log4j2 ] No grammar constraints (DTD or XML Schema) referenced in the document.
  5. codeforces 527 C Glass Carving
  6. linux 常用文本操作相关命令
  7. CSS display属性学习
  8. mybatis+springMVC
  9. 用xstart远程连接linux图形用户界面时发生已经在使用的情况
  10. Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间