Submission #211778

#TimeUsernameProblemLanguageResultExecution timeMemory
211778nicolaalexandraTraffickers (RMI18_traffickers)C++14
60 / 100
1198 ms524292 KiB
/// yay heavy /// nu mi place acel mle #include <bits/stdc++.h> #define DIM 30010 using namespace std; vector <short> L[DIM],w,aux; //vector <short> chains[DIM]; short chains[DIM]; vector <long long> aib[22][22][DIM]; short whatChain[DIM],positionInChain[DIM],chainFatherNode[DIM],Size[DIM]; short E[DIM*3],level[DIM],fth[DIM],first[DIM],p[DIM*3]; pair <short,short> rmq[20][DIM]; int n,m,i,j,x,y,tip,q,k,t1,t2,nr_chains; long long sum; void update_aib (int a, int b, int chain, int p, int n, int val){ for (;p<=n;p+=(p&-p)) aib[a][b][chain][p] += val; } long long query_aib (int a, int b, int chain, int p){ if (!p) return 0; long long sol = 0; for (;p;p-=(p&-p)) sol += aib[a][b][chain][p]; return sol; } long long get_sum (int a, int b, int chain, int x, int y){ return query_aib (a,b,chain,y) - query_aib (a,b,chain,x-1); } void dfs (int nod, int tata){ E[++k] = nod; first[nod] = k; fth[nod] = tata; level[nod] = 1 + level[tata]; Size[nod] = 1; int ok = 0; for (auto vecin : L[nod]){ if (vecin != tata){ ok = 1; dfs (vecin,nod); E[++k] = nod; Size[nod] += Size[vecin]; }} if (!ok){ nr_chains++; //chains[nr_chains].push_back(0); //chains[nr_chains].push_back(nod); chains[nr_chains] = 1; positionInChain[nod] = 1; whatChain[nod] = nr_chains; } else { int maxim = 0, poz = 0; for (auto vecin : L[nod]){ if (vecin == tata) continue; if (Size[vecin] > maxim) maxim = Size[vecin], poz = vecin; } chains[whatChain[poz]]++; positionInChain[nod] = chains[whatChain[poz]]; whatChain[nod] = whatChain[poz]; for (auto vecin : L[nod]){ if (vecin == tata || vecin == poz) continue; chainFatherNode[whatChain[vecin]] = 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 drum (int x, int y){ int lca = get_lca (x,y); w.clear(); int nod = x; while (nod != lca){ w.push_back(nod); nod = fth[nod]; } w.push_back(lca); nod = y; aux.clear(); while (nod != lca){ aux.push_back(nod); nod = fth[nod]; } for (j=aux.size()-1;j>=0;j--) w.push_back(aux[j]); } void adauga (int x, int y){ drum (x,y); /// in w am lantul de la x la y int t = 0, lg = w.size(); for (auto nod : w){ update_aib(t,lg,whatChain[nod],positionInChain[nod],chains[whatChain[nod]],1); t++; } } void scoate (int x, int y){ drum (x,y); int t = 0, lg = w.size(); for (auto nod : w){ update_aib(t,lg,whatChain[nod],positionInChain[nod],chains[whatChain[nod]],-1); t++; } } void query_heavy (int x, int y, int a, int b){ if (whatChain[x] == whatChain[y]){ int posx = positionInChain[x], posy = positionInChain[y]; if (posx > posy) swap (posx, posy); sum += get_sum (a,b,whatChain[x],posx,posy); return; } if (level[chainFatherNode[whatChain[x]]] <= level[chainFatherNode[whatChain[y]]]) swap (x,y); int posx = positionInChain[x], posy = chains[whatChain[x]]; sum += get_sum (a,b,whatChain[x],posx,posy); int nr = chainFatherNode[whatChain[x]]; query_heavy (nr,y,a,b); } long long solve (int x, int y, int t){ if (t < 0) return 0; long long sol = 0; for (int a=0;a<=20;a++){ if (a > t) break; for (int b=1;b<=20;b++){ int nr = (t - a) / b + 1; sum = 0; query_heavy (x,y,a,b); sol += 1LL * nr * sum; } } return sol; } int main (){ // ifstream cin ("traffickers.in"); // ofstream cout ("traffickers.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 (int a=0;a<=20;a++) for (int b=0;b<=20;b++) for (i=1;i<=nr_chains;i++) for (j=0;j<=chains[i];j++) aib[a][b][i].push_back(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; cin>>m; /// nr inital de traficanti for (i=1;i<=m;i++){ cin>>x>>y; adauga (x,y); } cin>>q; for (;q--;){ cin>>tip>>x>>y; if (tip == 1){ adauga (x,y); continue; } if (tip == 2){ scoate (x,y); continue; } cin>>t1>>t2; cout<<solve(x,y,t2) - solve(x,y,t1-1)<<"\n"; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...