• CF 1076E Vasya and a Tree(线段树+树剖)


    传送门

    解题思路

      首先按照每个修改时(x)的深度(+d)从大到小排序,然后按照深度分层,一层一层的修改,修改的时候就直接暴力修改子树,然后每做完一层把答案都取下来,因为以后的所有修改的深度都小于当前层,也就是无法对当前层的节点造成贡献。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    const int MAXN = 300005;
    typedef long long LL;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    
    void out(LL x){
    	if(!x) return;
    	out(x/10);putchar('0'+x%10);
    }	
    
    inline void OUT(LL x){
    	if(!x) putchar('0');
    	else out(x);
    	putchar(' ');
    }
    
    int n,m,head[MAXN],cnt,to[MAXN<<1],nxt[MAXN<<1],Max;
    int dep[MAXN],fa[MAXN],son[MAXN],siz[MAXN],id[MAXN],top[MAXN],num;
    LL sum[MAXN<<2],tag[MAXN<<2],ans[MAXN];
    vector<int> a[MAXN];
    
    struct Query{
    	int v,d,rt;
    	friend bool operator<(const Query A,const Query B){
    		return A.d>B.d;
    	}
    }q[MAXN];
    
    inline int max(int x,int y){
    	return x>y?x:y;
    }
    
    inline int min(int x,int y){
    	return x<y?x:y;
    }
    
    inline void add(int bg,int ed){
    	to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void dfs1(int x,int f,int d){
    	dep[x]=d;fa[x]=f;siz[x]=1;Max=max(Max,d);a[d].push_back(x);
    	int maxson=-1,u;
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(u==f) continue;
    		dfs1(u,x,d+1);siz[x]+=siz[u];
    		if(siz[u]>maxson) maxson=siz[u],son[x]=u;
    	}
    }
    
    void dfs2(int x,int topf){
    	top[x]=topf;id[x]=++num;int u;
    	if(!son[x]) return;dfs2(son[x],topf);
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(u==fa[x] || u==son[x]) continue;
    		dfs2(u,u);
    	}
    }
    
    inline void pushdown(int x,int ln,int rn){
    	tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];
    	sum[x<<1]+=tag[x]*ln;sum[x<<1|1]+=tag[x]*rn;
    	tag[x]=0;
    }
    
    void update(int x,int l,int r,int L,int R,int k){
    	if(L<=l && r<=R){
    		sum[x]+=(LL)(r-l+1)*k;
    		tag[x]+=k;return ;
    	}
    	int mid=(l+r)>>1;if(tag[x]) pushdown(x,mid-l+1,r-mid);
    	if(mid>=L) update(x<<1,l,mid,L,R,k);
    	if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    
    LL query(int x,int l,int r,int L){
    	if(l==r) return sum[x];
    	int mid=(l+r)>>1;LL ret=0;if(tag[x]) pushdown(x,mid-l+1,r-mid);
    	if(L<=mid) return query(x<<1,l,mid,L);
    	else return query(x<<1|1,mid+1,r,L);
    }
    
    int main(){
    	n=rd();int x,y,z;
    	for(int i=1;i<n;i++){
    		x=rd(),y=rd();
    		add(x,y),add(y,x);
    	}
    	dfs1(1,0,1);dfs2(1,1);m=rd();
    	for(int i=1;i<=m;i++){	
    		x=rd(),y=rd(),z=rd();
    		q[i].rt=x;q[i].d=min(dep[x]+y,Max);q[i].v=z;
    	}
    	sort(q+1,q+1+m);
    	for(int i=1;i<=m;i++){
    		x=q[i].rt,y=q[i].d,z=q[i].v;
    		if(y!=q[i-1].d)
    			for(int j=q[i-1].d;j>y;j--)
    				for(int k=0;k<a[j].size();k++)
    					ans[a[j][k]]=query(1,1,n,id[a[j][k]]);
    		update(1,1,n,id[x],id[x]+siz[x]-1,z);
    	}
    	for(int i=q[m].d;i;i--)
    		for(int j=0;j<a[i].size();j++)
    			ans[a[i][j]]=query(1,1,n,id[a[i][j]]);
    	for(int i=1;i<=n;i++) OUT(ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    异常部分
    5.Spring Cloud初相识-------Hystrix熔断器
    4.Spring Cloud初相识--------Feign负载均衡
    3.Spring Cloud初相识--------Ribbon客户端负载均衡
    2.Spring Cloud初相识--------Eureka服务注册与消费
    17、SpringBoot------整合dubbo
    3.Hadoop测试Yarn和MapReduce
    2.Hadoop集群安装进阶
    1.Hadoop集群安装部署
    3.Netty的粘包、拆包(二)
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10065496.html
Copyright © 2020-2023  润新知