cf1076E Vasya and a Tree (线段树)

我的做法:

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

官方做法比较妙妙:

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

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

  1 #pragma GCC optimize(3)
  2 #include<bits/stdc++.h>
  3 #define pa pair<ll,ll>
  4 #define CLR(a,x) memset(a,x,sizeof(a))
  5 using namespace std;
  6 typedef long long ll;
  7 const int maxn=3e5+10;
  8 
  9 inline char gc(){
 10     return getchar();
 11     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
 12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
 13 }
 14 inline ll rd(){
 15     ll x=0;char c=gc();bool neg=0;
 16     while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
 17     while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
 18     return neg?(~x+1):x;
 19 }
 20 
 21 struct Q{
 22     int p,d,x;
 23 };
 24 int N,M,mdep,eg[maxn*2][2],egh[maxn],ect;
 25 int dfn[maxn][2],tot,dep[maxn];
 26 vector<int> poi[maxn];
 27 vector<Q> que[maxn];
 28 ll v[maxn<<2],laz[maxn<<2];
 29 
 30 
 31 inline void adeg(int a,int b){
 32     eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect;
 33 }
 34 
 35 inline void dfs(int x,int f){
 36     dfn[x][0]=++tot;mdep=max(mdep,dep[x]);
 37     poi[dep[x]].push_back(x);
 38     for(int i=egh[x];i;i=eg[i][1]){
 39         int b=eg[i][0];if(b==f) continue;
 40         dep[b]=dep[x]+1;dfs(b,x);
 41     }
 42     dfn[x][1]=tot;
 43 }
 44 
 45 inline void pushdown(int p){
 46     if(!laz[p]) return;
 47     int a=p<<1,b=p<<1|1;
 48     laz[a]+=laz[p],v[a]+=laz[p];
 49     laz[b]+=laz[p],v[b]+=laz[p];
 50     laz[p]=0;
 51 }
 52 
 53 inline void add(int p,int l,int r,int x,int y,int z){
 54     if(x<=l&&r<=y){
 55         v[p]+=z,laz[p]+=z;
 56     }else{
 57         int m=l+r>>1;
 58         pushdown(p);
 59         if(x<=m) add(p<<1,l,m,x,y,z);
 60         if(y>=m+1) add(p<<1|1,m+1,r,x,y,z);
 61     }
 62 }
 63 
 64 inline void change(int p,int l,int r,int x,int y){
 65     if(l==r) v[p]=y;
 66     else{
 67         int m=l+r>>1;pushdown(p);
 68         if(x<=m) change(p<<1,l,m,x,y);
 69         else change(p<<1|1,m+1,r,x,y);
 70     }
 71 }
 72 
 73 ll ans[maxn];
 74 inline void query(int p,int l,int r){
 75     if(l==r) ans[l]=v[p];
 76     else{
 77         pushdown(p);
 78         int m=l+r>>1;
 79         query(p<<1,l,m);query(p<<1|1,m+1,r);
 80     }
 81 }
 82 
 83 int main(){
 84     //freopen("","r",stdin);
 85     int i,j,k;
 86     N=rd();
 87     for(i=1;i<N;i++){
 88         int a=rd(),b=rd();
 89         adeg(a,b);adeg(b,a);
 90     }M=rd();
 91     dep[1]=1;dfs(1,0);
 92     for(i=1;i<=M;i++){
 93         Q q;
 94         q.p=rd(),q.d=rd(),q.x=rd();
 95         que[min(dep[q.p]+q.d,mdep)].push_back(q);
 96     }
 97     for(i=1;i<=mdep;i++){
 98         for(j=0;j<poi[i].size();j++) change(1,1,N,dfn[poi[i][j]][0],0);
 99         for(j=0;j<que[i].size();j++){
100             int p=que[i][j].p;
101             add(1,1,N,dfn[p][0],dfn[p][1],que[i][j].x);
102         }
103     }
104     query(1,1,N);
105     for(i=1;i<=N;i++)
106         printf("%I64d ",ans[dfn[i][0]]);
107     return 0;
108 }
原文地址:https://www.cnblogs.com/Ressed/p/9967271.html