zoukankan      html  css  js  c++  java
  • 牛客练习赛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.
    }
    
  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12586951.html
Copyright © 2011-2022 走看看