Submission #1156820

#TimeUsernameProblemLanguageResultExecution timeMemory
1156820AlgorithmWarriorFactories (JOI14_factories)C++20
100 / 100
4458 ms241048 KiB
#include "factories.h" #include <bits/stdc++.h> using namespace std; int const MAX=5e5+5; struct edge{ int nod,len; }; vector<edge>tree[MAX]; bool dead[MAX]; int centroid_dad[MAX]; int subsize[MAX]; int get_subsize(int nod,int tata){ subsize[nod]=1; for(auto [fiu,w] : tree[nod]) if(!dead[fiu] && fiu!=tata) subsize[nod]+=get_subsize(fiu,nod); return subsize[nod]; } int find_centroid(int nod,int tata,int total_sz){ for(auto [fiu,w] : tree[nod]) if(!dead[fiu] && fiu!=tata && subsize[fiu]>total_sz/2) return find_centroid(fiu,nod,total_sz); return nod; } int whole_centroid; int const LOG=23; long long dist_cen[MAX][LOG]; void get_distance(int nod,int tata,long long dist,int niv){ dist_cen[nod][niv]=dist; for(auto [fiu,w] : tree[nod]) if(!dead[fiu] && fiu!=tata) get_distance(fiu,nod,dist+w,niv); } void decompose(int nod,int niv,int last_centroid){ int total_sz=get_subsize(nod,-1); int centroid=find_centroid(nod,-1,total_sz); if(whole_centroid==-1) whole_centroid=centroid; centroid_dad[centroid]=last_centroid; dead[centroid]=1; for(auto [vec,w] : tree[centroid]) if(!dead[vec]) get_distance(vec,centroid,w,niv); for(auto [vec,w] : tree[centroid]) if(!dead[vec]) decompose(vec,niv+1,centroid); } void Init(int N, int A[], int B[], int D[]) { int i; for(i=0;i<N-1;++i){ tree[A[i]].push_back({B[i],D[i]}); tree[B[i]].push_back({A[i],D[i]}); } whole_centroid=-1; decompose(0,0,-1); } vector<int>blue_nodes[MAX]; vector<int>red_nodes[MAX]; vector<int>active_sons[MAX]; bool active[MAX]; void add_node(int nod,vector<int>location[]){ int ancestor=nod; while(ancestor!=-1){ location[ancestor].push_back(nod); if(!active[ancestor]){ active[ancestor]=1; int father=centroid_dad[ancestor]; if(father!=-1) active_sons[father].push_back(ancestor); } ancestor=centroid_dad[ancestor]; } } long long const INF=1e18; void minself(long long& x,long long val){ if(x>val) x=val; } long long find_min_distance(int nod,int niv){ long long dist_blue=INF,dist_red=INF; long long dist=INF; for(auto node : blue_nodes[nod]) if(node==nod) dist_blue=0; for(auto node : red_nodes[nod]) if(node==nod) dist_red=0; if(dist_blue==0 && dist_red==0) dist=0; for(auto son : active_sons[nod]){ for(auto node : blue_nodes[son]) minself(dist,dist_cen[node][niv]+dist_red); for(auto node : red_nodes[son]) minself(dist,dist_cen[node][niv]+dist_blue); for(auto node : blue_nodes[son]) minself(dist_blue,dist_cen[node][niv]); for(auto node : red_nodes[son]) minself(dist_red,dist_cen[node][niv]); } for(auto son : active_sons[nod]) minself(dist,find_min_distance(son,niv+1)); return dist; } void clear_vectors(int nod){ int ancestor=nod; while(ancestor!=-1){ blue_nodes[ancestor].clear(); red_nodes[ancestor].clear(); active_sons[ancestor].clear(); active[ancestor]=0; ancestor=centroid_dad[ancestor]; } } long long Query(int S, int X[], int T, int Y[]) { int i; for(i=0;i<S;++i) add_node(X[i],blue_nodes); for(i=0;i<T;++i) add_node(Y[i],red_nodes); long long dist=find_min_distance(whole_centroid,0); for(i=0;i<S;++i) clear_vectors(X[i]); for(i=0;i<T;++i) clear_vectors(Y[i]); return dist; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...