Submission #145267

#TimeUsernameProblemLanguageResultExecution timeMemory
145267TadijaSebezUnique Cities (JOI19_ho_t5)C++11
100 / 100
1691 ms85020 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back const int N=200050; vector<int> E[N]; int col[N],dep[N],par[N]; void DEP(int u, int p) { dep[u]=dep[p]+1; par[u]=p; for(int v:E[u]) if(v!=p) DEP(v,u); } int cen,den,n,m; int type[N]; bool on_d[N]; const int M=2*N; const int L=18; struct SegmentTree { int mx[M],ls[M],rs[M],lzy[M],tsz,root,n; SegmentTree(){} void init(){ for(int i=1;i<=tsz;i++) ls[i]=rs[i]=mx[i]=lzy[i]=0;root=tsz=n=0;} void Build(int &c, int ss, int se, int a[]) { c=++tsz;lzy[c]=0; if(ss==se){ mx[c]=a[ss];return;} int mid=ss+se>>1; Build(ls[c],ss,mid,a); Build(rs[c],mid+1,se,a); mx[c]=max(mx[ls[c]],mx[rs[c]]); } void Build(int _n, int a[]){ n=_n;Build(root,1,n,a);} void Set(int c, int ss, int se, int qs, int qe, int f) { if(qs>qe || qs>se || ss>qe) return; if(qs<=ss && qe>=se){ lzy[c]+=f;mx[c]+=f;return;} int mid=ss+se>>1; Set(ls[c],ss,mid,qs,qe,f); Set(rs[c],mid+1,se,qs,qe,f); mx[c]=max(mx[ls[c]],mx[rs[c]])+lzy[c]; } void Set(int qs, int qe, int f){ Set(root,1,n,qs,qe,f);} int Get(int c, int ss, int se, int qs, int qe) { if(qs<=ss && qe>=se) return mx[c]; int mid=ss+se>>1; if(qe<=mid) return Get(ls[c],ss,mid,qs,qe)+lzy[c]; if(qs>mid) return Get(rs[c],mid+1,se,qs,qe)+lzy[c]; return max(Get(ls[c],ss,mid,qs,qe),Get(rs[c],mid+1,se,qs,qe))+lzy[c]; } int Get(int qs, int qe){ return Get(root,1,n,qs,qe);} } ST; int lid[N],rid[N],tid,a[N]; void DFS(int u, int p) { dep[u]=dep[p]+1; lid[u]=++tid; a[tid]=dep[u]; for(int v:E[u]) if(v!=p) DFS(v,u); rid[u]=tid; } int cnt[N],anc[N][L],ans[N],sum; bool work[N]; int GetAnc(int u, int k) { for(int i=0;i<L;i++) if(k>>i&1) u=anc[u][i]; return u; } void Add(int u) { cnt[col[u]]++; if(cnt[col[u]]==1) sum++; } void Del(int u) { cnt[col[u]]--; if(cnt[col[u]]==0) sum--; } void Solve(int u, int p, int t) { if(on_d[u] && type[u]==t) work[u]=1; if(work[u]) { for(int v:E[u]) if(v!=p) work[v]=1; } anc[u][0]=p; for(int i=1;i<L;i++) anc[u][i]=anc[anc[u][i-1]][i-1]; vector<int> add; ST.Set(lid[u],rid[u],-2); int myd=ST.Get(lid[u],lid[u]); int d=ST.Get(lid[u],rid[u])-myd; int z=GetAnc(u,d); if(z!=0 && ST.Get(lid[z],rid[z])==ST.Get(lid[z],lid[z])) { if(anc[z][0]) add.pb(anc[z][0]); } z=anc[z][0]; if(z!=0 && ST.Get(lid[z],rid[z])==ST.Get(lid[z],lid[z])) { if(anc[z][0]) add.pb(anc[z][0]); } for(int v:add) Add(v); if(work[u]) { //printf("%i %i :%i\n",u,t,sum); ans[u]=sum; } for(int v:E[u]) if(v!=p) Solve(v,u,t); ST.Set(lid[u],rid[u],2); for(int v:add) Del(v); } void Solve(int u, int t) { for(int i=1;i<=n;i++) work[i]=0; ST.init();tid=0; DFS(u,0); ST.Build(tid,a); Solve(u,0,t); } int main() { int u,v; scanf("%i %i",&n,&m); for(int i=1;i<n;i++) scanf("%i %i",&u,&v),E[u].pb(v),E[v].pb(u); for(int i=1;i<=n;i++) scanf("%i",&col[i]); DEP(1,0);for(int i=1;i<=n;i++) if(dep[i]>dep[cen]) cen=i; DEP(cen,0);for(int i=1;i<=n;i++) if(dep[i]>dep[den]) den=i; for(int i=den;i;i=par[i]) on_d[i]=1; int hal=dep[den]/2; for(int i=den;dep[i]>hal;i=par[i]) type[i]=1; Solve(cen,1); Solve(den,0); for(int i=1;i<=n;i++) printf("%i\n",ans[i]); return 0; }

Compilation message (stderr)

joi2019_ho_t5.cpp: In member function 'void SegmentTree::Build(int&, int, int, int*)':
joi2019_ho_t5.cpp:27:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid=ss+se>>1;
           ~~^~~
joi2019_ho_t5.cpp: In member function 'void SegmentTree::Set(int, int, int, int, int, int)':
joi2019_ho_t5.cpp:37:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid=ss+se>>1;
           ~~^~~
joi2019_ho_t5.cpp: In member function 'int SegmentTree::Get(int, int, int, int, int)':
joi2019_ho_t5.cpp:46:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid=ss+se>>1;
           ~~^~~
joi2019_ho_t5.cpp: In function 'int main()':
joi2019_ho_t5.cpp:126:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%i %i",&n,&m);
  ~~~~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:127:54: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i=1;i<n;i++) scanf("%i %i",&u,&v),E[u].pb(v),E[v].pb(u);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
joi2019_ho_t5.cpp:128:29: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i=1;i<=n;i++) scanf("%i",&col[i]);
                        ~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...