# [BZOJ4372]烁烁的游戏

## Description

Q x：询问x的点权。
M x d w：将树上与节点x距离不超过d的节点的点权均加上w。

7 6
1 2
1 4
1 5
2 3
2 7
5 6
M 1 1 2
Q 5
M 2 2 3
Q 3
M 1 2 1
Q 2

2
3
6

## HINT

n，m<=10^5,|w|<=10^4

$LCA$再往上会被它的儿子容斥掉

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 100010
#define ls ch[node][0]
#define rs ch[node][1]
using namespace std;
char ch=getchar();int x=0;
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
int n,m,num,cnt,root,S;
int rt1[M],rt2[M],val[M<<8],ch[M<<8][2];bool vis[M];
struct point{int next,to;}e[M<<1];
e[num].to=to;
}
void dfs1(int x) {
sz[x]=1;deep[x]=deep[fa[x]]+1;
int to=e[i].to;
if(fa[x]==to) continue;
fa[to]=x,dfs1(to),sz[x]+=sz[to];
if(sz[to]>sz[son[x]]) son[x]=to;
}
}
void dfs2(int x,int tp) {
top[x]=tp;
if(son[x]) dfs2(son[x],tp);
if(e[i].to!=son[x]&&e[i].to!=fa[x])
dfs2(e[i].to,e[i].to);
}
int lca(int x,int y) {
while(top[x]!=top[y]) {
if(deep[top[x]]<deep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return deep[x]>deep[y]?y:x;
}
int dis(int x,int y) {
return deep[x]+deep[y]-2*deep[lca(x,y)];
}
void getroot(int x,int fa) {
size[x]=1;maxn[x]=0;
int to=e[i].to;
if(to==fa||vis[to]) continue;
getroot(to,x);
size[x]+=size[to];
maxn[x]=max(maxn[x],size[to]);
}
maxn[x]=max(maxn[x],S-size[x]);
if(maxn[x]<maxn[root]) root=x;
}
void solve(int x,int fa) {
vis[x]=true;f[x]=fa;
int to=e[i].to;
if(vis[to]) continue;
root=0,S=size[to],getroot(to,0);
solve(root,x);
}
}
void change(int &node,int l,int r,int l1,int r1,int v) {
if(!node) node=++cnt;
if(l1<=l&&r1>=r) {
val[node]+=v;return;
}
int mid=(l+r)/2;
if(l1<=mid) change(ls,l,mid,l1,r1,v);
if(r1>mid) change(rs,mid+1,r,l1,r1,v);
}
int query(int node,int l,int r,int x) {
if(!node) return 0;
if(l==r) return val[node];
int mid=(l+r)/2;
if(x<=mid) return val[node]+query(ls,l,mid,x);
else return val[node]+query(rs,mid+1,r,x);
}
void update(int x,int d,int v) {
change(rt1[x],0,n,0,d,v);
for(int i=x;f[i];i=f[i]) {
int dt=dis(x,f[i]);
if(dt>d) continue;
change(rt1[f[i]],0,n,0,d-dt,v);
change(rt2[i],0,n,0,d-dt,v);
}
}
int res=query(rt1[x],0,n,0);
for(int i=x;f[i];i=f[i]) {
int dt=dis(x,f[i]);
res+=query(rt1[f[i]],0,n,dt)-query(rt2[i],0,n,dt);
}
return res;
}
int main() {
for(int i=1;i<n;i++) {
}
dfs1(1),dfs2(1,1);
maxn[0]=S=n;
getroot(1,0),solve(root,0);
for(int i=1;i<=m;i++) {
char s[10];scanf("%s",s);
if(s[0]=='M') {
update(x,d,w);
}
else {
}