cf1076E Vasya and a Tree (线段树)

时间:2023-03-09 09:05:09
cf1076E Vasya and a Tree (线段树)

我的做法:

给询问按$deep[v]+d$排序,每次做到某一深度的时候,先给这个深度所有点的值清0,然后直接改v的子树

官方做法比较妙妙:

dfs,进入v的时候给$[deep[v],deep[v]+d]+=x$,出来的时候再减回来

日常忘开longlong,这回事变量开了输出没开

 #pragma GCC optimize(3)
#include<bits/stdc++.h>
#define pa pair<ll,ll>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=3e5+; inline char gc(){
return getchar();
static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
ll x=;char c=gc();bool neg=;
while(c<''||c>''){if(c=='-') neg=;c=gc();}
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
return neg?(~x+):x;
} struct Q{
int p,d,x;
};
int N,M,mdep,eg[maxn*][],egh[maxn],ect;
int dfn[maxn][],tot,dep[maxn];
vector<int> poi[maxn];
vector<Q> que[maxn];
ll v[maxn<<],laz[maxn<<]; inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} inline void dfs(int x,int f){
dfn[x][]=++tot;mdep=max(mdep,dep[x]);
poi[dep[x]].push_back(x);
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f) continue;
dep[b]=dep[x]+;dfs(b,x);
}
dfn[x][]=tot;
} inline void pushdown(int p){
if(!laz[p]) return;
int a=p<<,b=p<<|;
laz[a]+=laz[p],v[a]+=laz[p];
laz[b]+=laz[p],v[b]+=laz[p];
laz[p]=;
} inline void add(int p,int l,int r,int x,int y,int z){
if(x<=l&&r<=y){
v[p]+=z,laz[p]+=z;
}else{
int m=l+r>>;
pushdown(p);
if(x<=m) add(p<<,l,m,x,y,z);
if(y>=m+) add(p<<|,m+,r,x,y,z);
}
} inline void change(int p,int l,int r,int x,int y){
if(l==r) v[p]=y;
else{
int m=l+r>>;pushdown(p);
if(x<=m) change(p<<,l,m,x,y);
else change(p<<|,m+,r,x,y);
}
} ll ans[maxn];
inline void query(int p,int l,int r){
if(l==r) ans[l]=v[p];
else{
pushdown(p);
int m=l+r>>;
query(p<<,l,m);query(p<<|,m+,r);
}
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}M=rd();
dep[]=;dfs(,);
for(i=;i<=M;i++){
Q q;
q.p=rd(),q.d=rd(),q.x=rd();
que[min(dep[q.p]+q.d,mdep)].push_back(q);
}
for(i=;i<=mdep;i++){
for(j=;j<poi[i].size();j++) change(,,N,dfn[poi[i][j]][],);
for(j=;j<que[i].size();j++){
int p=que[i][j].p;
add(,,N,dfn[p][],dfn[p][],que[i][j].x);
}
}
query(,,N);
for(i=;i<=N;i++)
printf("%I64d ",ans[dfn[i][]]);
return ;
}