Submission #185354

#TimeUsernameProblemLanguageResultExecution timeMemory
185354nicolaalexandraRailway (BOI17_railway)C++14
100 / 100
758 ms131944 KiB
#include <bits/stdc++.h> #define DIM 1000010 using namespace std; int whatChain[DIM],positionInChain[DIM],chainFatherNode[DIM],Size[DIM],level[DIM]; int viz[DIM],low[DIM],niv[DIM],b[DIM],E[DIM*3],first[DIM],fth[DIM],p[DIM],v[DIM]; pair <int,int> rmq[20][DIM*3]; map <pair<int,int>,int> mch; vector <int> chains[DIM],L[DIM],sol; vector <pair<int,int> > a[DIM]; int n,m,k,i,j,nod,nr_chains,x,y,nr,lca,aux,K; void dfs (int nod, int tata){ E[++k] = nod; first[nod] = k; niv[nod] = 1 + niv[tata]; fth[nod] = tata; for (auto vecin:L[nod]){ if (vecin != tata){ dfs (vecin,nod); E[++k] = nod; }} } void pre_dfs (int nod, int tata){ viz[nod] = Size[nod] = 1; level[nod] = 1+level[tata]; int ok = 0; for (int i=0;i<L[nod].size();i++){ int vecin = L[nod][i]; if (!viz[vecin]){ ok = 1; pre_dfs (vecin,nod); Size[nod] += Size[vecin]; /// cate noduri am in subarbore }} if (!ok){ /// inseamna ca e frunza deci incep un nou lant nr_chains++; chains[nr_chains].push_back(0); /// le vreau indexate de la 1 chains[nr_chains].push_back(nod); whatChain[nod] = nr_chains; /// pe ce lant se afla x positionInChain[nod] = 1; /// pozitia in lant } else { /// pun nodul curent la capatul lantului fiului cel mai "greu", adica cel care Size ul maxim int maxim = 0, poz = 0; for (int i=0;i<L[nod].size();i++){ int fiu = L[nod][i]; if (fiu == tata) continue; if (Size[fiu] > maxim){ maxim = Size[fiu]; poz = fiu; }} /// acum il atasez la fiu chains[whatChain[poz]].push_back(nod); whatChain[nod] = whatChain[poz]; positionInChain[nod] = chains[whatChain[poz]].size()-1; /// acum calculez chain father node for (int i=0;i<L[nod].size();i++){ int fiu = L[nod][i]; if (fiu == tata) continue; if (fiu != poz) chainFatherNode[whatChain[fiu]] = nod; }}} void update_lazy (int chain, int nod, int st, int dr){ a[chain][nod].first += (dr-st+1)*a[chain][nod].second; if (st != dr){ a[chain][2*nod].second += a[chain][nod].second; a[chain][2*nod+1].second += a[chain][nod].second; } a[chain][nod].second = 0; return; } void update_aint (int chain, int nod, int st, int dr, int x, int y, int val){ update_lazy(chain,nod,st,dr); if (st > dr || x > y || x > dr || y < st) return; if (x <= st && dr <= y){ a[chain][nod].second += val; update_lazy (chain,nod,st,dr); return; } int mid = (st+dr)/2; update_aint(chain,2*nod,st,mid,x,y,val); update_aint(chain,2*nod+1,mid+1,dr,x,y,val); a[chain][nod].first = a[chain][2*nod].first + a[chain][2*nod+1].first; return; } int query_aint (int chain, int nod, int st, int dr, int poz){ update_lazy(chain,nod,st,dr); if (st == dr) return a[chain][nod].first; int mid = (st+dr)>>1; if (poz <= mid) query_aint (chain,nod<<1,st,mid,poz); else query_aint (chain,(nod<<1)|1,mid+1,dr,poz); } void update_heavy (int x, int y, int val){ if (whatChain[x] == whatChain[y]){ int posx = positionInChain[x], posy = positionInChain[y]; if (posx > posy) swap (posx,posy); if (x == nod) posx++; if (y == nod) posy--; if (posx > posy) return; update_aint (whatChain[x],1,1,chains[whatChain[x]].size()-1,posx,posy,val); return; } if (level[chainFatherNode[whatChain[x]]] <= level[chainFatherNode[whatChain[y]]]) swap (x,y); int poz_st = positionInChain[x], poz_dr = chains[whatChain[x]].size()-1; if (chains[whatChain[x]][poz_st] == nod) poz_st++; if (chains[whatChain[x]][poz_dr] == nod) poz_dr--; if (poz_st <= poz_dr) update_aint (whatChain[x],1,1,chains[whatChain[x]].size()-1,poz_st,poz_dr,val); int nr = chainFatherNode[whatChain[x]]; update_heavy (nr,y,val); } int get_lca (int x, int y){ int pozx = first[x], pozy = first[y]; if (pozx > pozy) swap (pozx,pozy); int nr = p[pozy-pozx+1]; pair <int,int> sol = min (rmq[nr][pozx],rmq[nr][pozy-(1<<nr)+1]); return E[sol.second]; } inline int cmp (int a, int b){ return first[a] < first[b]; } int main (){ //ifstream cin ("date.in"); //ofstream cout ("date.out"); cin>>n>>m>>K; for (i=1;i<n;i++){ cin>>x>>y; L[x].push_back(y); L[y].push_back(x); mch[make_pair(x,y)] = i; mch[make_pair(y,x)] = i; } dfs (1,0); for (i=1;i<=k;i++) rmq[0][i] = make_pair(niv[E[i]],i); for (i=1;(1<<i)<=k;i++) for (j=1;j<=k;j++){ rmq[i][j] = rmq[i-1][j]; if (j+(1<<(i-1)) <= k && rmq[i-1][j+(1<<(i-1))].first < rmq[i][j].first) rmq[i][j] = rmq[i-1][j+(1<<(i-1))]; } for (i=2;i<=k;i++) p[i] = p[i/2]+1; /// heavy pre_dfs(1,0); for (i=1;i<=nr_chains;i++){ for (int j=0;j<2*chains[i].size();j++) a[i].push_back(make_pair(0,0)); } for (i=1;i<=m;i++){ cin>>nr; for (j=1;j<=nr;j++) cin>>v[j]; /// determin lca-ul tuturor int lca = get_lca (v[1],v[2]); for (j=3;j<=nr;j++) lca = get_lca (lca,v[j]); v[++nr] = lca; sort (v+1,v+nr+1,cmp); /// elimin dublurile int nr2 = 1; for (j=2;j<=nr;j++) v[++nr2] = v[j]; nr = nr2; aux = v[1]; for (j=2;j<=nr;j++){ lca = get_lca (aux,v[j]); /// fac update pe lantul lca...v[j], dar nu trb sa fac si in lca nod = lca; update_heavy(v[j],lca,1); aux = v[j]; } /*s.clear(); s.push_back(v[1]); for (i=2;i<=n;i++){ /// elimin din stiva cat timp nu e un stramos while (!s.empty() && verif(v[s.back()],v[i])) s.pop_back(); x = v[s.back()], y = v[i]; /// trb sa fac update pe lantul asta, dar sa nu fac update in x!! nod = x; update_heavy (x,y,1); }*/ } for (i=2;i<=n;i++){ int val = query_aint (whatChain[i],1,1,chains[whatChain[i]].size()-1,positionInChain[i]); if (val >= K) sol.push_back(mch[make_pair(i,fth[i])]); } sort (sol.begin(),sol.end()); cout<<sol.size()<<"\n"; for (auto it:sol) cout<<it<<" "; return 0; }

Compilation message (stderr)

railway.cpp: In function 'void pre_dfs(int, int)':
railway.cpp:26:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i=0;i<L[nod].size();i++){
                  ~^~~~~~~~~~~~~~
railway.cpp:42:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i=0;i<L[nod].size();i++){
                      ~^~~~~~~~~~~~~~
railway.cpp:55:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i=0;i<L[nod].size();i++){
                      ~^~~~~~~~~~~~~~
railway.cpp: In function 'int main()':
railway.cpp:169:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j=0;j<2*chains[i].size();j++)
                      ~^~~~~~~~~~~~~~~~~~~
railway.cpp: In function 'int query_aint(int, int, int, int, int)':
railway.cpp:96:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
#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...