• 牛客练习赛60 旗鼓相当的对手 [长链剖分/dsu on tree]


    瞎搞题,乱写都能过。

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int maxn = 2e5 + 52;
    int n, k;
    int a[maxn];
    vector<int> g[maxn];
    int son[maxn], len[maxn];
    void dfs(int u, int fa) {
        for (int v : g[u]) {
            if (v == fa) continue;
            dfs(v, u);
            if (len[v] > len[son[u]]) son[u] = v;
        }
        len[u] = len[son[u]] + 1;
    }
    int dfn[maxn], idx = 0;
    void dfsdfn(int u, int fa) {
        dfn[u] = ++idx;
        if (son[u]) dfsdfn(son[u], u);
        for (int v : g[u])
            if (v != fa && v != son[u]) dfsdfn(v, u);
    }
    int cnt[maxn];
    int sum[maxn];
    int ans[maxn];
    void dfsans(int u, int fa) {
        if (son[u]) dfsans(son[u], u);
        for (int v : g[u]) {
            if (v != fa && v != son[u]) {
                dfsans(v, u);
                for (int j = 1; j <= len[v]; j++) {
                    if (j == k) break;
                    if(k - j < len[u]) ans[u] += cnt[dfn[u] + k - j] * sum[dfn[v] + j - 1];
                    if(k - j < len[u]) ans[u] += sum[dfn[u] + k - j] * cnt[dfn[v] + j - 1];
                }
                for (int j = 1; j <= len[v]; j++) {
                    cnt[dfn[u] + j] += cnt[dfn[v] + j - 1];
                }
                for (int j = 1; j <= len[v]; j++) {
                    sum[dfn[u] + j] += sum[dfn[v] + j - 1];
                }
            }
        }
        cnt[dfn[u]] = 1;
        sum[dfn[u]] = a[u];
    }
    signed main() {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 2; i <= n; i++) {
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, 0);
        dfsdfn(1, 0);
        dfsans(1, 0);
        for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
        cout << endl;
        return 0;
    }
    
    // clang-format off
    // powered by c++11
    // by Isaunoya
    #include<bits/stdc++.h>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define Rep(i,x,y) for(register int i=(x);i>=(y);--i)
    using namespace std;using db=double;using ll=long long;
    using uint=unsigned int;using ull=unsigned long long;
    using pii=pair<int,int>;
    #define Tp template
    #define fir first
    #define sec second
    Tp<class T>void cmax(T&x,const T&y){if(x<y)x=y;}Tp<class T>void cmin(T&x,const T&y){if(x>y)x=y;}
    #define all(v) v.begin(),v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    Tp<class T>void sort(vector<T>&v){sort(all(v));}Tp<class T>void reverse(vector<T>&v){reverse(all(v));}
    Tp<class T>void unique(vector<T>&v){sort(all(v)),v.erase(unique(all(v)),v.end());}inline void reverse(string&s){reverse(s.begin(),s.end());}
    const int SZ=1<<23|233;
    struct FILEIN{char qwq[SZ],*S=qwq,*T=qwq,ch;
    #ifdef __WIN64
    #define GETC getchar
    #else
    inline char GETC(){return(S==T)&&(T=(S=qwq)+fread(qwq,1,SZ,stdin),S==T)?EOF:*S++;}
    #endif
    inline FILEIN&operator>>(char&c){while(isspace(c=GETC()));return*this;}inline FILEIN&operator>>(string&s){s.clear();while(isspace(ch=GETC()));if(!~ch)return*this;s=ch;while(!isspace(ch=GETC())&&~ch)s+=ch;return*this;}
    inline FILEIN&operator>>(char*str){char*cur=str;while(*cur)*cur++=0;cur=str;while(isspace(ch=GETC()));if(!~ch)return*this;*cur=ch;while(!isspace(ch=GETC())&&~ch)*++cur=ch;*++cur=0;return*this;}
    Tp<class T>inline void read(T&x){bool f=0;while((ch=GETC())<48&&~ch)f^=(ch==45);x=~ch?(ch^48):0;while((ch=GETC())>47)x=x*10+(ch^48);x=f?-x:x;}
    inline FILEIN&operator>>(int&x){return read(x),*this;}inline FILEIN&operator>>(ll&x){return read(x),*this;}inline FILEIN&operator>>(uint&x){return read(x),*this;}inline FILEIN&operator>>(ull&x){return read(x),*this;}
    inline FILEIN&operator>>(double&x){read(x);bool f=x<0;x=f?-x:x;if(ch^'.')return*this;double d=0.1;while((ch=GETC())>47)x+=d*(ch^48),d*=.1;return x=f?-x:x,*this;}
    }in;
    struct FILEOUT{const static int LIMIT=1<<22;char quq[SZ],ST[233];int sz,O,pw[233];
    FILEOUT(){set(7);rep(i,pw[0]=1,9)pw[i]=pw[i-1]*10;}~FILEOUT(){flush();}
    inline void flush(){fwrite(quq,1,O,stdout),fflush(stdout),O=0;}
    inline FILEOUT&operator<<(char c){return quq[O++]=c,*this;}inline FILEOUT&operator<<(string str){if(O>LIMIT)flush();for(char c:str)quq[O++]=c;return*this;}
    inline FILEOUT&operator<<(char*str){if(O>LIMIT)flush();char*cur=str;while(*cur)quq[O++]=(*cur++);return*this;}
    Tp<class T>void write(T x){if(O>LIMIT)flush();if(x<0){quq[O++]=45;x=-x;}do{ST[++sz]=x%10^48;x/=10;}while(x);while(sz)quq[O++]=ST[sz--];}
    inline FILEOUT&operator<<(int x){return write(x),*this;}inline FILEOUT&operator<<(ll x){return write(x),*this;}inline FILEOUT&operator<<(uint x){return write(x),*this;}inline FILEOUT&operator<<(ull x){return write(x),*this;}
    int len,lft,rig;void set(int l){len=l;}inline FILEOUT&operator<<(double x){bool f=x<0;x=f?-x:x,lft=x,rig=1.*(x-lft)*pw[len];return write(f?-lft:lft),quq[O++]='.',write(rig),*this;}
    }out;
    #define int long long
    struct Math{
    vector<int>fac,inv;int mod;
    void set(int n,int Mod){fac.resize(n+1),inv.resize(n+1),mod=Mod;rep(i,fac[0]=1,n)fac[i]=fac[i-1]*i%mod;inv[n]=qpow(fac[n],mod-2);Rep(i,n-1,0)inv[i]=inv[i+1]*(i+1)%mod;}
    int qpow(int x,int y){int ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1)ans=ans*x%mod;return ans;}int C(int n,int m){if(n<0||m<0||n<m)return 0;return fac[n]*inv[m]%mod*inv[n-m]%mod;}
    int gcd(int x,int y){return!y?x:gcd(y,x%y);}int lcm(int x,int y){return x*y/gcd(x,y);}
    }math;
    // clang-format on
    
    int n, k;
    const int maxn = 1e5 + 51;
    int a[maxn];
    vector < int > g[maxn];
    int depcnt[maxn], depval[maxn];
    int fa[maxn];
    int dep[maxn], son[maxn], sz[maxn], ans[maxn];
    void dfs(int u) {
    	sz[u] = 1;
    	for(int v : g[u]) {
    		if(v == fa[u]) continue;
    		fa[v] = u;
    		dep[v] = dep[u] + 1;
    		dfs(v);
    		sz[u] += sz[v];
    		if(sz[v] > sz[son[u]])
    			son[u] = v;
    	}
    }
    
    int sum = 0;
    void calc(int u, int lca) {
    	int d = k + dep[lca] * 2 - dep[u];
    	if(d > 0) {
    		sum += depval[d];
    		sum += depcnt[d] * a[u];
    	}
    	for(int v : g[u]) 
    		if(v ^ fa[u])
    			calc(v , lca);
    }
    
    void add(int u, int val) {
    	depcnt[dep[u]] += val;
    	depval[dep[u]] += val * a[u];
    	for(int v : g[u])
    		if(v ^ fa[u])
    			add(v , val);
    }
    
    void dfs2(int u, int kep) {
    	for(int v : g[u])
    		if(v ^ fa[u] && v ^ son[u])
    			dfs2(v , 0);
    	if(son[u])
    		dfs2(son[u] , 1);
    	for(int v : g[u])
    		if(v ^ fa[u] && v ^ son[u])
    			calc(v , u), add(v , 1);
    	ans[u] = sum;
    	depcnt[dep[u]] ++, depval[dep[u]] += a[u];
    	if(! kep)
    		add(u , -1);
    	sum = 0;
    }
    
    signed main(){
    	//code begin.
    	in >> n >> k;
    	rep(i , 1 , n)
    		in >> a[i];
    	rep(i , 2 , n) {
    		int u , v;
    		in >> u >> v;
    		g[u].pb(v);
    		g[v].pb(u);
    	}
    	dfs(1);
    	dfs2(1 , 1);
    	rep(i , 1 , n)
    		out << ans[i] << ' ';
    	return 0;
    	//code end.
    }
    
  • 相关阅读:
    VNC远程控制软件是什么?有没有更好的远程桌面控制解决方案?
    目前国内最热门的四款远程桌面控制软件
    深入Redis命令的执行过程
    深入Redis客户端(redis客户端属性、redis缓冲区、关闭redis客户端)
    Springboot拦截器的使用
    Springboot使用Undertow
    Jenkins parallel并行构建
    Jenkins使用docker构建
    Redis 的键命令、HyperLogLog 命令、脚本命令、连接命令、服务器命令
    Redis Set和ZSet常用命令
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12586951.html
Copyright © 2020-2023  润新知