Submission #225229

#TimeUsernameProblemLanguageResultExecution timeMemory
225229MKopchevCat in a tree (BOI17_catinatree)C++14
100 / 100
472 ms156908 KiB
#include<bits/stdc++.h> using namespace std; const int nmax=1e6+42; long long n,d; vector< pair<int/*to*/,int/*dist*/> > adj[nmax]; long long depth[nmax]; vector<int> output; int up[20][nmax]; int level[nmax]; int in[nmax],out[nmax]; int seen[nmax],t=0; pair<int/*min level*/,int/*node*/> table[20][nmax]; void dfs(int node,int par) { up[0][node]=par; level[node]=level[par]+1; t++; in[node]=t; seen[t]=node; for(auto k:adj[node]) if(k.first!=par) { depth[k.first]=depth[node]+k.second; dfs(k.first,node); t++; seen[t]=node; } t++; seen[t]=node; out[node]=t; } int inv[nmax]; int query(int l,int r) { int k=inv[r-l+1]; return min(table[k][l],table[k][r-(1<<k)+1]).second; } int lca(int u,int v) { return query(min(in[u],in[v]),max(out[u],out[v])); } long long tree_dist(int u,int v) { return depth[u]+depth[v]-2*depth[lca(u,v)]; } bool been[nmax]; int parent_centroid[nmax]; long long nearest[nmax]; int SZ[nmax]; void dfs_sz(int node,int par) { SZ[node]=1; for(auto k:adj[node]) if(k.first!=par&&been[k.first]==0) { dfs_sz(k.first,node); SZ[node]+=SZ[k.first]; } } int centroid(int node) { dfs_sz(node,0); int low=SZ[node]/2; while(1) { bool stop=1; for(auto k:adj[node]) if(SZ[node]>SZ[k.first]&&SZ[k.first]>low) { node=k.first; stop=0; break; } if(stop)break; } return node; } int decomp(int node) { node=centroid(node); been[node]=1; for(auto k:adj[node]) if(been[k.first]==0) { parent_centroid[decomp(k.first)]=node; } return node; } priority_queue< pair<long long,int> > pq; long long closest(int node) { long long ret=1e18; int help=node; while(help) { ret=min(ret,tree_dist(node,help)+nearest[help]); help=parent_centroid[help]; } return ret; } int go_up(int node) { int help=node; for(int i=19;i>=0;i--) if(depth[node]-depth[up[i][help]]<=d)help=up[i][help]; return help; } void update(int node) { int help=node; while(help) { nearest[help]=min(nearest[help],tree_dist(help,node)); help=parent_centroid[help]; } } int main() { scanf("%lld%lld",&n,&d); int u,v,dist; for(int i=1;i<n;i++) { scanf("%i",&v); u=i+1; v++; //cout<<u<<" "<<v<<endl; adj[u].push_back({v,1}); adj[v].push_back({u,1}); } dfs(1,1); for(int i=1;i<=t;i++) table[0][i]={level[seen[i]],seen[i]}; for(int st=1;st<20;st++) for(int i=1;i+(1<<st)-1<=t;i++) table[st][i]=min(table[st-1][i],table[st-1][i+(1<<(st-1))]); for(int i=1;i<=t;i++) { while(2*(1<<inv[i])<i)inv[i]++; } for(int st=1;st<20;st++) for(int i=1;i<=n;i++) up[st][i]=up[st-1][up[st-1][i]]; decomp(1); /* for(int i=1;i<=t;i++) { cout<<seen[i]<<" "; } cout<<endl; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cout<<lca(i,j)<<" "; } cout<<endl; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cout<<tree_dist(i,j)<<" "; } cout<<endl; } cout<<"t= "<<t<<endl; for(int i=1;i<=n;i++)cout<<i<<" -> "<<parent_centroid[i]<<endl; */ for(int i=1;i<=n;i++)nearest[i]=1e18; for(int i=1;i<=n;i++)pq.push({depth[i],i}); while(pq.size()) { pair<long long,int> tp=pq.top(); pq.pop(); /* cout<<"---"<<endl; for(int i=1;i<=n;i++) cout<<i<<" -> "<<closest(i)<<endl; */ if(closest(tp.second)<d)continue; int actual=tp.second; output.push_back(actual); update(actual); /* cout<<"update "<<actual<<endl; cout<<"nearest: "<<endl; for(int i=1;i<=n;i++) cout<<i<<" -> "<<nearest[i]<<endl; cout<<"---"<<endl; */ } sort(output.begin(),output.end()); printf("%i\n",output.size()); /* for(int i=0;i<output.size();i++) { printf("%i",output[i]); if(i==output.size()-1)printf("\n"); else printf(" "); } */ return 0; }

Compilation message (stderr)

catinatree.cpp: In function 'int main()':
catinatree.cpp:251:32: warning: format '%i' expects argument of type 'int', but argument 2 has type 'std::vector<int>::size_type {aka long unsigned int}' [-Wformat=]
     printf("%i\n",output.size());
                   ~~~~~~~~~~~~~^
catinatree.cpp:154:13: warning: unused variable 'dist' [-Wunused-variable]
     int u,v,dist;
             ^~~~
catinatree.cpp:152:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%lld%lld",&n,&d);
     ~~~~~^~~~~~~~~~~~~~~~~~
catinatree.cpp:157:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%i",&v);
         ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...