LG6782 rplexq

#include<bits/stdc++.h>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forUP(i,a,b) for(int i=(a);i<(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
#define forG(u,v) for(int __i=head[u],v=to[__i];__i;__i=nxt[__i],v=to[__i])
#define forWG(u,v,c) for(int __i=head[u],v=to[__i],c=w[__i];__i;__i=nxt[__i],v=to[__i],c=w[__i])
#define pushb push_back
#define popb pop_back
#define pushf push_front
#define popf pop_front
#define popc __builtin_popcount
#define popc64 __builtin_popcountll
#define seteps(n) fixed<<setprecision(n)
bool __mst;using uint=unsigned int;using int64=long long;using uint64=unsigned long long;using int128=__int128;using uint128=unsigned __int128;using float64=double;using float80=long double;
constexpr int INF=0x3f3f3f3f,MINF=0xcfcfcfcf;constexpr int64 INF64=0x3f3f3f3f3f3f3f3f,MINF64=0xcfcfcfcfcfcfcfcf;constexpr float64 INFDB=1e50,eps=1e-6;
template<class _Tp>inline void chkMax(_Tp &x,const _Tp &y){if(x<y)x=y;}template<class _Tp>inline void chkMin(_Tp &x,const _Tp &y){if(x>y)x=y;}
inline int addMod(const int &x,const int &y,const int mod){int ans=x+y;return ans>=mod?ans-mod:ans;}inline int subMod(const int &x,const int &y,const int mod){int ans=x-y;return ans<0?ans+mod:ans;}
constexpr int N=2e5+10,S=447,B=447,NB=B+10;int __test_num=1,__task_id,__tst;using namespace std;void __init();

int n,q,root;vector<int> T[N],G[N];

int DFN,dfn[N],rk[N],sz[N];
void dfs(int rt,int fa){
	sz[rk[dfn[rt]=++DFN]=rt]=1;
	for(int son:T[rt])if(son!=fa)dfs(son,rt),G[rt].pushb(son),sz[rt]+=sz[son];
}

int count(int l,int r,int u){
	int ans=0;
	forUP(i,dfn[u],dfn[u]+sz[u])ans+=l<=rk[i]&&rk[i]<=r;
	return ans*ans;
}
namespace DS1{ // sz_u > S  log - log
	int c[N];
	void add(int pos){for(;pos<=n;pos+=pos&-pos)++c[pos];}
	int ask(int pos){int ans=0;for(;pos;pos&=pos-1)ans+=c[pos];return ans;}
	int ask(int l,int r){return ask(r)-ask(l-1);}
}
int blng[N],btot,L[NB],R[NB];
void build(){
	L[0]=1-B;btot=(n-1)/B+1;forUp(i,1,btot){
		L[i]=L[i-1]+B,R[i]=min(R[i-1]+B,n);
		forUp(pos,L[i],R[i])blng[pos]=i;
	}
}
namespace DS2{ // sz_v > S  sqrt - 1
	int cnt[N],sum[NB];
	void add(int pos){
		forUp(k,pos,R[blng[pos]])++cnt[k];
		forUp(k,blng[pos]+1,btot)++sum[k];
	}
	int ask(int pos){return sum[blng[pos]]+cnt[pos];}
	int ask(int l,int r){return ask(r)-ask(l-1);}
}
namespace DS3{ // sz_v <= S  1 - sqrt
	int cnt[N],sum[NB];
	void add(int pos,int val){cnt[pos]+=val;sum[blng[pos]]+=val;}
	int ask(int pos){
		int ans=0;
		forUP(k,1,blng[pos])ans+=sum[k];
		forUp(k,L[blng[pos]],pos)ans+=cnt[k];
		return ans;
	}
}

int64 ans[N],res1[N],res2[N];int tot,tmp[N],cov[N];vector<array<int,3>> ask12[N];vector<array<int,2>> ask3[N];
void solve(int rt,int fa){
	if(sz[rt]>S){
		for(auto [qid,l,r]:ask12[rt])res1[qid]=-DS1::ask(l,r);
		for(auto [qid,l,r]:ask12[fa])res2[qid]=-DS2::ask(l,r);
	}
	DS1::add(rt);DS2::add(rt);
	for(int son:G[rt])solve(son,rt);
	if(sz[rt]>S){
		tot=0;for(int son:G[rt])if(sz[son]<=S)forUP(i,dfn[son],dfn[son]+sz[son])tmp[++tot]=rk[i],cov[rk[i]]=son;
		sort(tmp+1,tmp+tot+1);forUp(i,1,tot)ask3[i].clear();
		for(auto [qid,l,r]:ask12[rt]){
			int lid=lower_bound(tmp+1,tmp+tot+1,l)-tmp;
			ask3[lid].pushb({qid,r});
		}
		forDown(i,tot,1){
			int u=tmp[i],son=cov[u];
			forUP(j,dfn[son],dfn[son]+sz[son]){
				if(rk[j]>u)DS3::add(rk[j],2);
				else if(rk[j]==u)DS3::add(u,1);
			}
			for(auto [qid,r]:ask3[i])ans[qid]-=DS3::ask(r);
		}
		forDown(i,tot,1){
			int u=tmp[i],son=cov[u];
			forUP(j,dfn[son],dfn[son]+sz[son]){
				if(rk[j]>u)DS3::add(rk[j],-2);
				else if(rk[j]==u)DS3::add(u,-1);
			}
		}
		for(auto [qid,l,r]:ask12[rt])res1[qid]+=DS1::ask(l,r),ans[qid]+=res1[qid]*res1[qid];
		for(auto [qid,l,r]:ask12[fa])res2[qid]+=DS2::ask(l,r),ans[qid]-=res2[qid]*res2[qid];
	}
}

// l = 156 r = 560 u = 19
bool __med;void __solve(int __test_id){
	cin>>n>>q>>root;
	forUP(i,1,n){
		int u,v;cin>>u>>v;
		T[u].pushb(v);T[v].pushb(u);
	}
	dfs(root,0);build();
	forUp(qid,1,q){
		int l,r,u;cin>>l>>r>>u;ans[qid]-=l<=u&&u<=r;
		if(sz[u]<=S){
			ans[qid]+=count(l,r,u);
			for(int v:G[u])ans[qid]-=count(l,r,v);
		}
		else ask12[u].pushb({qid,l,r});
	}
	solve(root,0);
	forUp(i,1,q)cout<<ans[i]/2<<'\n';
}
signed main(){
	__init();
	forUp(i,1,__test_num)__solve(i);
	cerr<<1000.0*(clock()-__tst)/CLOCKS_PER_SEC<<"ms "<<((&__mst)-(&__med))/1024.0/1024.0<<"MB"<<'\n';
	return 0;
}
void __init(){
	__tst=clock();
	#ifndef use_file
	//#define use_file
	#endif
	#ifdef use_file
	const string __file_name="test";freopen((__file_name+".in").c_str(),"r",stdin);freopen((__file_name+".out").c_str(),"w",stdout);
	#endif
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//scanf("%d",&__test_num);
	//cin>>__test_num;
}
posted @ 2026-03-13 17:33  LXcjh4998  阅读(1)  评论(0)    收藏  举报