zoukankan      html  css  js  c++  java
  • 牛客练习赛60E

     利用树上DSU来统计每一个点的答案

    #include<bits/stdc++.h>
    #define forn(i, s, t) for (int i = s ; i < (int)t ; i++)
    #define fi first
    #define se second
    #define all(x) x.begin(),x.end()
    #define pf2(x,y) printf("%d %d
    ",x,y)
    #define pf(x) printf("%d
    ",x)
    #define each(x) for(auto it:x)  cout<<it<<endl;
    #define pi pair<int,int>
    #define pb push_back
    #define sc(x) scanf("%d",&x)
    #define sc2(x,y) scanf("%d%d",&x,&y) 
    #define pf(x) printf("%d
    ",x)
    #define pf2(x,y) printf("%d %d
    ",x,y)
    #define mem(a,x) memset(a,x,sizeof(a))
    #define copy(b,a) memcpy(a,b,sizeof(a))
    #define SZ(x) (int)x.size()
    #define VI vector<int> 
    #define VII vector<pair<int,int>> 
    #define PI pair<int,int>
    using namespace std;
    typedef long long ll;
    const ll P=1e9+7;
    const int maxn=1e5+5;
    const int maxm=2e5+5;
    int head[maxn],ver[maxm],nex[maxm],tot,n,k;
    void inline AddEdge(int x,int y){
    	ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
    }
    int size[maxn],son[maxn],cnt[maxn],vis[maxn],dep[maxn],ar[maxn];
    ll sum[maxn],ans[maxn];
    void dfs(int x,int pa){
    	size[x]=1;
    	dep[x]=dep[pa]+1;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa) continue;
    		dfs(y,x);
    		size[x]+=size[y];
    		if(!son[x] || size[y]>size[son[x]]) son[x]=y;
    	}
    }
    void add(int x,int pa,int op){
    	sum[dep[x]]+=op*ar[x];
    	cnt[dep[x]]+=op;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa) continue;
    		add(y,x,op);
    	}
    }
    void qry(int x,int pa,int lca){
    	int d=k+2*dep[lca]-dep[x];
    	if(d>0) {
    		ans[lca]+=sum[d];
    		ans[lca]+=cnt[d]*ar[x];
    	}
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa) continue;
    		qry(y,x,lca);
    	}
    }
    void dfs(int x,int pa,bool keep){
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa || y==son[x]) continue;
    		dfs(y,x,0);
    	}
    	if(son[x]) dfs(son[x],x,1),vis[son[x]]=1;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa || vis[y]) continue;
    		qry(y,x,x);
    		add(y,x,1);
    	}
    	cnt[dep[x]]++;
    	sum[dep[x]]+=ar[x];
    	if(son[x]) vis[son[x]]=0;
    	if(!keep){
    		for(int i=head[x];i;i=nex[i]){
    			int y=ver[i];
    			if(y==pa) continue;
    			add(y,x,-1);
    		}
    		cnt[dep[x]]--;
    		sum[dep[x]]-=ar[x];
    	}
    }
    
    int main(){
    	sc2(n,k);
    	forn(i,1,n+1)
    		sc(ar[i]);
    	forn(i,1,n){
    		int x,y;
    		sc2(x,y);
    		AddEdge(x,y);
    		AddEdge(y,x);
    	}
    	dfs(1,0);
    	dfs(1,0,1);
    	forn(i,1,n+1)
    		printf("%lld%c",ans[i]," 
    "[i==n]);
    }
    

      

  • 相关阅读:
    Android 内存剖析 – 发现潜在问题
    Android内存泄漏问题(一)
    Android的事件处理机制详解(二)-----基于监听的事件处理机制
    Android的事件处理机制(一)------基于回调机制的事件处理
    OOA、OOD 和 OOP
    面向对象初识
    Python 2 和 Python 3 的区别
    软件开发规范
    语法分析和词法分析
    循环删除的坑
  • 原文地址:https://www.cnblogs.com/033000-/p/12585635.html
Copyright © 2011-2022 走看看