제출 #1129204

#제출 시각아이디문제언어결과실행 시간메모리
1129204Math4Life2020Tourism (JOI23_tourism)C++20
0 / 100
5099 ms110908 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<ll,ll>; const ll Nm = 131072; const ll E = 17; vector<ll> fadj[Nm]; ll radj[Nm]; ll sz[Nm]; ll ht[Nm]; vector<ll> adj[Nm]; bool isHeavy[Nm]; //global memory -> all 0 by default ll hprt[Nm]; //heavy parent ll hsz[Nm]; //heavy path size ll memloc[Nm]; vector<ll> ett; //euler tour ll floc[Nm]; pii ettmin[2*Nm][E+2]; //{height,xval} vector<pii> hld[2*Nm]; //{elem,count} bool lazy[2*Nm]; //lazy tag on above ll ansST[2*Nm]; inline pii fz(pii p1, pii p2) { if (p1.first<p2.first) { return p1; } else { return p2; } } inline ll l2(ll x) { return (31-__builtin_clz(x)); } inline ll v2(ll x) { return __builtin_ctz(x); } void updT(ll x, ll v) { ansST[Nm+x]+=v; ll p = (Nm+x)/2; while (p>0) { ansST[p]=ansST[2*p]+ansST[2*p+1]; p=p/2; } } ll qryT(ll x) { if (x<0) { return 0; } ll vx = v2(x+1); return (ansST[(1LL<<(E-vx))+(x>>vx)]+qryT(x-(1LL<<vx))); } ll lca(ll x, ll y) { x = floc[x]; y = floc[y]; if (x>y) { swap(x,y); } ll l2d = l2(y-x+1); pii pf = fz(ettmin[x][l2d],ettmin[y-(1LL<<l2d)+1][l2d]); return pf.second; } void pdn(ll x) { if (x>=Nm || !lazy[x]) { return; } lazy[x]=0; lazy[2*x]=1; lazy[2*x+1]=1; hld[2*x+1]=hld[2*x]=(vector<pii>){{hld[x][0].first,hld[x][0].second/2}}; } void lft(ll x) { if (x>=Nm || lazy[x]) { return; } vector<pii> v1 = hld[2*x]; ll i1 = 0; vector<pii> v2 = hld[2*x+1]; ll i2 = 0; vector<pii> vf; while (i1<v1.size()||i2<v2.size()) { if (i1<v1.size() && i2<v2.size()) { if (v1[i1].first==v2[i2].first) { vf.push_back({v1[i1].first,v1[i1].second+v2[i2].second}); i1++; i2++; } else if (v1[i1].first>v2[i2].first) { vf.push_back(v2[i2]); i2++; } else { vf.push_back(v1[i1]); i1++; } } else if (i1==v1.size()) { vf.push_back(v2[i2++]); } else { vf.push_back(v1[i1++]); } } hld[x]=vf; } void stset(ll p, ll sz0, ll t) { for (pii p0: hld[p]) { if (p0.first==-1) { continue; } updT(p0.first,-p0.second); //cerr << "updT: t,val="<<p0.first<<","<<(-p0.second)<<"\n"; } hld[p]=(vector<pii>){{t,sz0}}; updT(t,sz0); //cerr << "updT: t,val="<<t<<","<<sz0<<"\n"; lazy[p]=1; } void updR(ll x, ll y, ll t) { //set segtree elements in [x,y] to all t //return; //cout << "updR on x,y,t="<<x<<","<<y<<","<<t<<"\n"; if (x>y) { return; } for (ll e=E;e>=0;e--) { pdn((x>>e)+(1LL<<(E-e))); pdn((y>>e)+(1LL<<(E-e))); } ll xc = x; ll yc = y; while (xc<=yc) { ll vx = v2(xc); ll vy = v2(yc+1); if (vx<vy) { stset((xc>>vx)+(1LL<<(E-vx)),(1LL<<vx),t); xc += (1LL<<vx); } else { stset((yc>>vy)+(1LL<<(E-vy)),(1LL<<vy),t); yc -= (1LL<<vy); } } bool lzyF = 0; for (ll e=0;e<=E;e++) { ll p = (x>>e)+(1LL<<(E-e)); if (lzyF) { lft(p); } else { if (lazy[p]) { lzyF=1; } } } lzyF=0; for (ll e=0;e<=E;e++) { ll p = (y>>e)+(1LL<<(E-e)); if (lzyF) { lft(p); } else { if (lazy[p]) { lzyF=1; } } } } //ll CLOCK = 0; void upd(ll x, ll y, ll t) { //update path x->y, set to time t //cout << "upd: x,y,t="<<x<<","<<y<<","<<t<<"\n"; // if (100<=CLOCK++) { // return; // } //return; if (ht[x]<ht[y] || x<0) { return; } if (ht[hprt[x]]>=ht[y]) { updR(memloc[hprt[x]],memloc[hprt[x]]+ht[x]-ht[hprt[x]],t); upd(radj[hprt[x]],y,t); } else { updR(memloc[hprt[x]]+ht[y]-ht[hprt[x]],memloc[hprt[x]]+ht[x]-ht[hprt[x]],t); } } int main() { ll N,M,Q; ios_base::sync_with_stdio(false); cin.tie(0); cin >> N >> M >> Q; for (ll i=0;i<(N-1);i++) { ll a,b; cin >> a >> b; a--; b--; adj[a].push_back(b); adj[b].push_back(a); } radj[0]=-1; ht[0]=0; queue<ll> q0; vector<ll> rtpls; q0.push(0); while (!q0.empty()) { ll x = q0.front(); q0.pop(); for (ll y: adj[x]) { if (y != radj[x]) { ht[y]=1+ht[x]; radj[y]=x; fadj[x].push_back(y); q0.push(y); rtpls.push_back(y); } } } for (ll t=(N-1);t>=0;t--) { ll x = rtpls[t]; hprt[x]=x; sz[x]=1; ll maxsz=-1; ll cstr=-1; for (ll y: fadj[x]) { sz[x]+=sz[y]; if (sz[y]>maxsz) { cstr = y; maxsz = sz[y]; } } if (cstr!=-1) { isHeavy[cstr]=1; } } for (ll t=0;t<N;t++) { ll x = rtpls[t]; if (isHeavy[x]) { hprt[x]=hprt[radj[x]]; hsz[hprt[x]]++; } } ll MLOC = 0; //memory location for (ll t=0;t<N;t++) { ll x = rtpls[t]; if (!isHeavy[x]) { memloc[x]=MLOC; hsz[x]++; MLOC += hsz[x]; } } stack<pii> s0; s0.push({0,0}); while (!s0.empty()) { pii p0 = s0.top(); s0.pop(); ll x = p0.first; ll t = p0.second; ett.push_back(x); if (t==0) { floc[x]=ett.size()-1; for (ll y: fadj[x]) { s0.push({x,1}); s0.push({y,0}); } } } assert(ett.size()<=(2*Nm)); for (ll t=0;t<ett.size();t++) { ettmin[t][0]={ht[ett[t]],ett[t]}; } for (ll e=1;e<=(E+1);e++) { for (ll t=0;t<=(2*Nm-(1LL<<e));t++) { ettmin[t][e]=fz(ettmin[t][e-1],ettmin[t+(1LL<<(e-1))][e-1]); } } for (ll t=1;t<(2*Nm);t++) { hld[t]=(vector<pii>){{-1,E-l2(t)}}; } vector<ll> cv; for (ll i=0;i<M;i++) { ll ci; cin >> ci; ci--; cv.push_back(ci); } vector<pair<ll,pii>> qryV; //{r,{l,qi}} ll ans[Q]; for (ll q=0;q<Q;q++) { ll l,r; cin >> l >> r; l--; r--; qryV.push_back({r,{l,q}}); } sort(qryV.begin(),qryV.end()); ll TR = 0; //upd(cv[0],cv[0],0); //cerr << "end op\n"; // cout << "ett vector:\n"; // for (ll x: ett) { // cout << x << " "; // } // cout << "\nfloc vector:\n"; // for (ll x=0;x<N;x++) { // cout << floc[x]<<" "; // } // exit(0); // for (ll x=0;x<N;x++) { // cout << "x="<<x<<"\n"; // cout << "isHeavy[x]="<<isHeavy[x]<<"\n"; // cout << "memloc[x]="<<memloc[x]<<"\n"; // } for (auto A: qryV) { ll r = A.first; ll l = A.second.first; ll q = A.second.second; if (r>TR) { while (r!=TR) { ll clca = lca(cv[TR],cv[TR+1]); //cout << "cv[TR],cv[TR+1],clca="<<cv[TR]<<","<<cv[TR+1]<<","<<clca<<"\n"; upd(cv[TR],clca,TR+1); //cout << "end op\n"; //cerr << "end op\n"; upd(cv[TR+1],clca,TR+1); //cout << "end op\n"; //cerr << "end op\n"; TR++; } } ll ansv = 0; ansv += qryT(r); ansv -= qryT(l); if (l==r) { ansv=1; } ans[q]=ansv; } for (ll m=0;m<=M;m++) { //cout << "qryT(t="<<m<<")="<<qryT(m)<<"\n"; //cout << "ansST[Nm+t]="<<ansST[Nm+m]<<"\n"; } for (ll q=0;q<Q;q++) { cout << ans[q] << "\n"; } }
#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...