【BZOJ4372】—烁烁的游戏(动态点分治)
动态点分治模板题
结果点分树建挂了。。。。
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=100005;
struct Bit{
vector<int> tr;
int n;
inline void init(int _n){
n=_n+1,tr.resize((n+1)<<2,0);
}
#define lb(x) (x&(-x))
inline void update(int p,int k){p++;p=min(p,n);
for(;p>=1;p-=lb(p))tr[p]+=k;
}
inline int query(int p,int res=0){p++;
if(p<=0)return 0;
for(;p<=n;p+=lb(p))res+=tr[p];return res;
}
};
Bit f1[N],f2[N];
int n,m,maxn,rt;
int siz[N],son[N],vis[N];
vector<pii> fa[N];
vector<int> e[N];
void getrt(int u,int f){
siz[u]=1,son[u]=0;
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==f||vis[v])continue;
getrt(v,u),siz[u]+=siz[v];
chemx(son[u],siz[v]);
}
son[u]=max(son[u],maxn-siz[u]);
if(son[u]<son[rt])rt=u;
}
int mxdep;
void getdep(int u,int f,int dep){
chemx(mxdep,dep);
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==f||vis[v])continue;
getdep(v,u,dep+1);
}
}
inline void init(Bit &x,int u,int dep){
mxdep=0;
getdep(u,0,dep);
x.init(mxdep);
}
void givefa(int u,int f,int dep,int ff){
fa[u].pb(pii(ff,dep));
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==f||vis[v])continue;
givefa(v,u,dep+1,ff);
}
}
void solve(int u,int f){
vis[u]=1;
init(f1[u],u,0),givefa(u,0,0,u);
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(vis[v])continue;
maxn=siz[v]>siz[u]?siz[f]-siz[u]:siz[v];
getrt(v,rt=0),init(f2[rt],v,1);
solve(rt,u);
}
}
inline int query(int u){
int res=0;pii x;
for(int i=fa[u].size()-1;~i;i--){
x=fa[u][i];
res+=f1[x.fi].query(x.se);
}
for(int i=fa[u].size()-1;i;i--){
res-=f2[fa[u][i].fi].query(fa[u][i-1].se);
}
return res;
}
inline void update(int u,int d,int k){
pii x;
for(int i=(int)fa[u].size()-1;~i;i--){
x=fa[u][i];
f1[x.fi].update(d-x.se,k);
}
for(int i=(int)fa[u].size()-1;i;i--){
f2[fa[u][i].fi].update(d-fa[u][i-1].se,k);
}
}
char op[4];
int main(){
n=read(),m=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
siz[0]=son[0]=maxn=n;
getrt(1,rt=0);
solve(rt,0);
while(m--){
scanf("%s",op+1);int x=read();
if(op[1]=='Q'){
cout<<query(x)<<'\n';
}
else{
int d=read(),w=read();
update(x,d,w);
}
}
}