Submission #1365026

#TimeUsernameProblemLanguageResultExecution timeMemory
1365026enzyPetrol stations (CEOI24_stations)C++20
0 / 100
289 ms25400 KiB
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int maxn=7e4+10;
int sub[maxn], tam, marc[maxn], ja[maxn], pai[maxn], k;
vector<pii>v[maxn], join[maxn];
// vector<int>join[maxn];
void dfs(int u){
    tam++; marc[u]++;
    sub[u]=1;
    for(pii p : v[u]){
        if(marc[p.fi]) continue;
        pai[p.fi]=u;
        dfs(p.fi);
        sub[u]+=sub[p.fi];
    }
}
int find_cd(int u){
    tam=0;
    pai[u]=0;
    dfs(u);
    int nxt=-1, at=u;
    while(true){
        // cerr << "> " << at << ' ' << sub[at] << '\n';
        bool flag=true;
        for(pii p : v[at]) if(ja[p.fi]==0&&p.fi!=pai[at]&&2*sub[p.fi]>tam) flag=false, nxt=p.fi;
        if(flag) return at;
        at=nxt; nxt=-1;
    }
}
vector<int>cd_decomp(int n){ // me parece certo o suficiente
    int qtd=0;
    vector<int>ret;
    while(qtd!=n){
        // cerr << "? " << qtd << '\n';
        for(int i=0;i<n;i++) marc[i]=0;
        for(int x : ret) marc[x]=1;
        for(int i=0;i<n;i++){
            if(!marc[i]){
                int at=find_cd(i);
                ret.push_back(at);
                // cerr << "! " << at << ": " << '\n';
                for(pii p : v[at]) if(!ja[p.fi]) join[at].push_back(p);
                // for(pii p : v[at]) if(!ja[p.fi]) cerr << p.fi << ' ';
                // cerr << '\n';
                ja[at]++;
                qtd++;
            }
        }
    }   
    return ret;
}
 
int cnt[maxn][11], cost[maxn], special[11], blocked[maxn], resp[maxn], n_sub[maxn], M=0;
 
void go(int u, int pai){
    // cerr << "visiting " << u << '\n';
    assert(!blocked[u]);
    int past[k+1];
    for(int i=0;i<=k;i++) past[i]=special[i];
    // for(int i=0;i<=k;i++) cerr << past[i] << ' ';
    // cerr << '\n';
    for(pii p : v[u]){
        if(p.fi==pai||blocked[p.fi]) continue;
        for(int i=0;i<p.se;i++) resp[u]+=past[i]*n_sub[p.fi];
        // if(u==3) cerr << "?? " << p.se << ' ' << k-p.se << '\n';
        // cerr << "!!! ";
        // for(int i=0;i<=k;i++) cerr << past[i] << ' ';
        // cerr << '\n';
        for(int i=0;i<=k;i++) special[i]=0;
        for(int i=0;i<p.se;i++) special[k-p.se]+=past[i];
        for(int i=p.se;i<=k;i++) special[i-p.se]+=past[i];
        // cerr << "$$$ ";
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';
        go(p.fi,u);
    }
}
 
void pre(int u, int pai){
    n_sub[u]=1;
    // cerr << "> " << u << '\n';
    for(int i=0;i<=k;i++) cnt[u][i]=0;
    cnt[u][k]=1;
    for(pii p : v[u]){
        if(blocked[p.fi]||p.fi==pai) continue;
        pre(p.fi,u);
        n_sub[u]+=n_sub[p.fi];
        for(int i=0;i<p.se;i++) cnt[u][k-p.se]+=cnt[p.fi][i];
        for(int i=p.se;i<=k;i++) cnt[u][i-p.se]+=cnt[p.fi][i];
    }
}
 
void adjust(int u, int pai){
    for(pii p : v[u]){
        if(blocked[p.fi]||p.fi==pai) continue;
        pre(p.fi,u);
        for(int i=0;i<p.se;i++) resp[p.fi]+=(M-n_sub[u])*cnt[p.fi][i];
    }
}
 
void calc(int u){ // vamos mergear todos os vizinhos de x =)
    // cerr << "calc " << u << '\n';
    cnt[u][k]=1;
    for(pii p : v[u]) cost[p.fi]=p.se;
    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        // cerr << "start: " << p.fi << '\n';
        pre(p.fi,p.fi);
        for(int i=0;i<p.se;i++){
            resp[p.fi]+=cnt[p.fi][i]*(M-n_sub[p.fi]);
            cnt[u][k-p.se]+=cnt[p.fi][i];
        }
        for(int i=p.se;i<=k;i++) cnt[u][i-p.se]+=cnt[p.fi][i];
    }
    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        adjust(p.fi,p.fi);
    }
    if(u==2){
        for(int i=0;i<6;i++){
            // cerr << "cnt: ";
            // for(int j=0;j<=k;j++) cerr << cnt[i][j] << ' ';
            // cerr << '\n';
        }
    }
    for(pii p : v[u]){
        if(blocked[p.fi]) continue;
        for(int i=0;i<=k;i++) special[i]=cnt[u][i];
 
        // cerr << "before go " << p.fi << '\n';
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';
 
        for(int i=0;i<p.se;i++) special[k-p.se]-=cnt[p.fi][i];
        for(int i=p.se;i<=k;i++) special[i-p.se]-=cnt[p.fi][i];
 
        // cerr << "go " << p.fi << '\n';
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';
 
        for(int i=0;i<p.se;i++) resp[u]+=special[i]*n_sub[p.fi];
        int aux[11]; memset(aux,0,sizeof(aux));
        for(int i=0;i<p.se;i++) aux[k-p.se]+=special[i];
        for(int i=p.se;i<=k;i++) aux[i-p.se]+=special[i];
        for(int i=0;i<=k;i++) special[i]=aux[i];
 
        // cerr << "just go " << p.fi << '\n';
        // cerr << "special: ";
        // for(int i=0;i<=k;i++) cerr << special[i] << ' ';
        // cerr << '\n';
 
        go(p.fi,u);
    }
    // cerr << "finish " << u << '\n';
    // cerr << "resp: ";
    // for(int i=0;i<6;i++) cerr << resp[i] << ' ';
    // cerr << '\n';    
    blocked[u]=0;
}
 
signed main(){
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n; cin >> n >> k;
    for(int i=1;i<n;i++){
        int a, b, c; cin >> a >> b >> c;
        v[a].push_back({b,c});
        v[b].push_back({a,c});
    }
    vector<int>roots=cd_decomp(n);
    // return 0;
    reverse(roots.begin(),roots.end());
    for(int i=0;i<n;i++) blocked[i]=1;
    for(int x : roots){
        M++;
        calc(x);
    }
    for(int i=0;i<n;i++) cout << resp[i] << '\n';
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...