Submission #1158895

#TimeUsernameProblemLanguageResultExecution timeMemory
1158895MighilonPetrol stations (CEOI24_stations)C++20
100 / 100
2837 ms1043644 KiB
#include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "../Library/debug.h" #else #define dbg(x...) #endif typedef long long ll; typedef long double ld; typedef pair<int, int> pi; typedef pair<ll, ll> pl; typedef vector<int> vi; typedef vector<bool> vb; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; #define FOR(i, a, b) for (int i = (a); i < (b); ++i) #define F0R(i, a) for (int i = 0; i < (a); ++i) #define FORd(i, a, b) for (int i = (b) - 1; i >= (a); --i) #define F0Rd(i, a) for (int i = (a) - 1; i >= 0; --i) #define trav(a, x) for (auto& a : x) #define f first #define s second #define pb push_back #define sz(x) (int)(x).size() #define all(x) x.begin(), x.end() const char nl = '\n'; const int INF = 1e9; // const ll MOD = 1e9 + 7; const ll MOD=998244353; int n; ll k; // vector<vi> adj; // vector<array<int,2>> e; // vi ans,sz,cnt,depth; // vb used; // vector<vl> dist,pred; const int mxN=70005; vi adj[mxN]; array<int,2> e[mxN]; ll ans[mxN],dist[20][mxN]; int sz[mxN],cnt[mxN],depth[mxN],pred[20][mxN]; bool used[mxN]; map<int,vpi> mp; struct node{ ll val; node*c[2]={nullptr,nullptr}; node():val(0){ } // ~node(){ // if(c[0]!=nullptr){ // c[0]->~node(); // node *tmp=c[0]; // c[0]=nullptr; // free(tmp); // } // if(c[1]!=nullptr){ // c[1]->~node(); // node *tmp=c[1]; // c[1]=nullptr; // free(tmp); // } // } void push(){ if(c[0]==nullptr) c[0]=new node(); if(c[1]==nullptr) c[1]=new node(); } void merge(){ if(c[0]&&c[1]) val=c[0]->val+c[1]->val; else if(c[0]) val=c[0]->val; else if(c[1]) val=c[1]->val; } void add(ll l, ll r, ll q, ll valq){ if(q<l||q>r)return; if(l==r&&l==q){ val+=valq; return; } ll m=l+(r-l)/2; if(q<=m){ if(c[0]==nullptr)c[0]=new node(); c[0]->add(l,m,q,valq); } else{ if(c[1]==nullptr)c[1]=new node(); c[1]->add(m+1,r,q,valq); } merge(); } ll query(ll l,ll r,ll ql,ll qr){ if(r<ql||l>qr)return 0; if(ql<=l&&r<=qr) return val; ll sum=0; ll m=l+(r-l)/2; // first optimization if(c[0]!=nullptr) sum+=c[0]->query(l,m,ql,qr); if(c[1]!=nullptr) sum+=c[1]->query(m+1,r,ql,qr); return sum; // return c[0]->query(l,m,ql,qr)+c[1]->query(m+1,r,ql,qr); } }; int size_tree(int v,int p=-1){ sz[v]=1; trav(id,adj[v]){ int u=e[id][0]^v; if(used[u]||u==p)continue; sz[v]+=size_tree(u,v); } return sz[v]; } int find_centroid(int v,int size,int p=-1){ trav(id,adj[v]){ int u=e[id][0]^v; if(u==p||used[u])continue; if(sz[u]>size/2) return find_centroid(u,size,v); } return v; } void up_stage(int v,int p,int w,int d,int st){ depth[v]=d; pred[0][v]=p; dist[0][v]=w; sz[v]=1; cnt[v]=1; FOR(i,1,20){ pred[i][v]=pred[i-1][pred[i-1][v]]; dist[i][v]=dist[i-1][v]+dist[i-1][pred[i-1][v]]; } trav(id,adj[v]){ int u=e[id][0]^v; if(used[u]||u==p)continue; up_stage(u,v,e[id][1],d+1,d==0?u:st); sz[v]+=sz[u]; } int u=v; ll dist_up=0; F0Rd(i,20){ if(dist_up+dist[i][u]<=k){ dist_up+=dist[i][u]; u=pred[i][u]; } } if(depth[u])cnt[u]+=cnt[v]; else mp[st].pb({k-dist_up,cnt[v]}); } void down_stage(int v,int p,ll d,node* tree,int tree_size,int st_sz=0){ ans[v]+=1LL*(cnt[v]-1)*(tree_size-st_sz); trav(id,adj[v]){ int u=e[id][0]^v; if(used[u]||u==p)continue; if(!d)trav(x,mp[u]){ tree->add(0,(n+1)*k,x.f,-x.s); } ll tmp=tree->query(0,(n+1)*k,d,d+e[id][1]-1); ans[v]+=tmp*sz[u]; tree->add(0,(n+1)*k,d+k,tmp); if(depth[v]==0)st_sz=sz[u]; down_stage(u,v,d+e[id][1],tree,tree_size,st_sz); tree->add(0,(n+1)*k,d+k,-tmp); if(!d)trav(x,mp[u])tree->add(0,(n+1)*k,x.f,x.s); } } void centroid_decomposition(int c){ int v=find_centroid(c,size_tree(c)); used[v]=true; up_stage(v,v,0,0,-1); node *tree=new node(); trav(i,mp) trav(x,i.s) tree->add(0,(n+1)*k,x.f,x.s); down_stage(v,v,0,tree,sz[v]); // free(tree); mp.clear(); trav(id,adj[v]){ int u=e[id][0]^v; if(used[u])continue; centroid_decomposition(u); } } void solve(){ cin>>n>>k; F0R(i,n-1){ int a,b; cin>>a>>b>>e[i][1]; e[i][0]=a^b; adj[a].pb(i); adj[b].pb(i); } centroid_decomposition(0); F0R(i,n)cout<<ans[i]<<nl; } int32_t main(){ ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int TC = 1; // cin >> TC; // auto start = chrono::steady_clock::now(); while(TC--){ solve(); } // auto end = chrono::steady_clock::now(); // dbg(chrono::duration_cast<chrono::milliseconds>(end-start).count()); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...