Submission #209560

#TimeUsernameProblemLanguageResultExecution timeMemory
209560nicolaalexandraMin-max tree (BOI18_minmaxtree)C++14
0 / 100
366 ms106724 KiB
/// stiu ca nu e bn #include <bits/stdc++.h> #define DIM 1000010 using namespace std; int whatChain[DIM],positionInChain[DIM],chainFatherNode[DIM],level[DIM],Size[DIM],fth[DIM]; int E[DIM*4],p[DIM*4],first[DIM],viz[DIM]; pair <int,int> rmq[30][DIM]; vector <int> chains[DIM],L[DIM]; int nr_chains; struct segment_tree{ int maxi,mini,lazy; }; vector <segment_tree> aint[DIM]; struct _update{ int x,y,val,dist; }; _update v[DIM]; int n,m,i,j,x,y,val,dist,lca,k; char ch; void dfs (int nod, int tata){ E[++k] = nod; first[nod] = k; viz[nod] = Size[nod] = 1; level[nod] = 1 + level[tata]; fth[nod] = tata; int ok = 0; for (int i=0;i<L[nod].size();i++){ int vecin = L[nod][i]; if (!viz[vecin]){ ok = 1; dfs (vecin,nod); Size[nod] += Size[vecin]; E[++k] = nod; }} if (!ok){ nr_chains++; chains[nr_chains].push_back(0); chains[nr_chains].push_back(nod); whatChain[nod] = nr_chains; positionInChain[nod] = 1; } else { 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; }} chains[whatChain[poz]].push_back(nod); whatChain[nod] = whatChain[poz]; positionInChain[nod] = chains[whatChain[poz]].size()-1; 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; }}} int get_lca (int x, int y){ int posx = first[x], posy = first[y]; if (posx > posy) swap (posx,posy); int nr = p[posy-posx+1]; pair <int,int> sol = min (rmq[nr][posx],rmq[nr][posy-(1<<nr)+1]); return E[sol.second]; } void update_lazy (int chain, int nod, int st, int dr){ if (!aint[chain][nod].lazy) return; if (st != dr){ int fiu_st = nod<<1, fiu_dr = (nod<<1)|1; aint[chain][fiu_st].mini = aint[chain][fiu_st].maxi = aint[chain][nod].lazy; aint[chain][fiu_dr].mini = aint[chain][fiu_dr].maxi = aint[chain][nod].lazy; aint[chain][fiu_st].lazy = aint[chain][fiu_dr].lazy = aint[chain][nod].lazy; } aint[chain][nod].lazy = 0; } void update_nod (int chain, int nod, int st, int dr){ int fiu_st = nod<<1, fiu_dr = (nod<<1)|1; aint[chain][nod].maxi = max (aint[chain][fiu_st].maxi,aint[chain][fiu_dr].maxi); aint[chain][nod].mini = min (aint[chain][fiu_st].mini,aint[chain][fiu_dr].mini); } void update_aint (int chain, int nod, int st, int dr, int x, int y, int val){ update_lazy (chain,nod,st,dr); if (x <= st && dr <= y){ aint[chain][nod].mini = aint[chain][nod].maxi = val; aint[chain][nod].lazy = val; update_lazy(chain,nod,st,dr); return; } int mid = (st+dr)>>1; if (x <= mid) update_aint(chain,nod<<1,st,mid,x,y,val); if (y > mid) update_aint(chain,(nod<<1)|1,mid+1,dr,x,y,val); update_lazy (chain,nod<<1,st,mid); update_lazy (chain,(nod<<1)|1,mid+1,dr); update_nod (chain,nod,st,dr); } int get_val (int chain, int nod, int st, int dr, int poz){ update_lazy(chain,nod,st,dr); if (st == dr) return aint[chain][nod].maxi; int mid = (st+dr)>>1; if (poz <= mid) return get_val (chain,nod<<1,st,mid,poz); else return get_val(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), swap (x,y); if (x == lca) posx++; if (y == lca) posy--; if (posx <= posy) 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 posx = positionInChain[x], posy = chains[whatChain[x]].size()-1; if (chains[whatChain[x]][posx] == lca) posx++; if (chains[whatChain[x]][posy] == lca) posy--; if (posx <= posy) update_aint(whatChain[x],1,1,chains[whatChain[x]].size()-1,posx,posy,val); int nr = chainFatherNode[whatChain[x]]; update_heavy (nr,y,val); } inline int cmp (_update a, _update b){ return a.dist > b.dist; } int main (){ // ifstream cin ("minmaxtree.in"); // ofstream cout ("minmaxtree.out"); cin>>n; for (i=1;i<n;i++){ cin>>x>>y; L[x].push_back(y); L[y].push_back(x); } dfs (1,0); for (i=1;i<=nr_chains;i++){ for (j=0;j<chains[i].size()*4;j++) aint[i].push_back({0,0,0}); } for (i=1;i<=k;i++) rmq[0][i] = make_pair (level[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; /// am numai maxime cin>>m; for (i=1;i<=m;i++){ cin>>ch>>x>>y>>val; lca = get_lca (x,y); dist = level[x] + level[y] - 2 * level[lca]; v[i] = {x,y,val,dist}; } sort (v+1,v+m+1,cmp); for (i=1;i<=m;i++){ int x = v[i].x, y = v[i].y, val = v[i].val; lca = get_lca (x,y); update_heavy(x,y,val); } for (i=2;i<=n;i++){ int val = get_val (whatChain[i],1,1,chains[whatChain[i]].size()-1,positionInChain[i]); cout<<i<<" "<<fth[i]<<" "<<val<<"\n"; } return 0; }

Compilation message (stderr)

minmaxtree.cpp: In function 'void dfs(int, int)':
minmaxtree.cpp:30:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i=0;i<L[nod].size();i++){
                  ~^~~~~~~~~~~~~~
minmaxtree.cpp:47:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i=0;i<L[nod].size();i++){
                      ~^~~~~~~~~~~~~~
minmaxtree.cpp:59:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int i=0;i<L[nod].size();i++){
                      ~^~~~~~~~~~~~~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:171:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (j=0;j<chains[i].size()*4;j++)
                  ~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...