Submission #1129200

#TimeUsernameProblemLanguageResultExecution timeMemory
1129200Math4Life2020Tourism (JOI23_tourism)C++20
0 / 100
5102 ms217552 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long; using pii = pair<ll,ll>;
const ll Nm = 262144; const ll E = 18;
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() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	ll N,M,Q; 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...