树剖lca为什么比倍增慢
查看原帖
树剖lca为什么比倍增慢
102709
zjy1412楼主2020/9/20 07:17

此题我先用的树剖lca然后TLE了,后来改成倍增就过了,为什么呢?是树剖比倍增慢吗?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define R register
#define int long long
inline int read(){
	int a=0,b=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')b=-1;c=getchar();}
	while(isdigit(c)){a=a*10+c-'0';c=getchar();}
	return a*b;
}
const int N=2e5+50,M=4e5+50;
struct node{
	int l,r,sum;
}t[6000050];
int n,m,q,a[N],b[N],tot,h[N],ver[M],nx[M],
cnt,d[N],size[N],son[N],top[N],rt[N],f[N][30];//,f[N];
void add(int u,int v){
	ver[++tot]=v;nx[tot]=h[u];
	h[u]=tot;
}
void build(int &p,int l,int r){
	p=++cnt;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(t[p].l,l,mid);build(t[p].r,mid+1,r);
}
void change(int &p,int pre,int l,int r,int k,int z){
	p=++cnt;
	t[p]=t[pre];t[p].sum+=z;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(k<=mid)change(t[p].l,t[pre].l,l,mid,k,z);
	else change(t[p].r,t[pre].r,mid+1,r,k,z);
}
int query(int u,int v,int fa,int faa,int l,int r,int k){
	if(l==r)return l;
	int sum=t[t[u].l].sum+t[t[v].l].sum-t[t[fa].l].sum-t[t[faa].l].sum;
	int mid=(l+r)>>1;
	if(k<=sum)return query(t[u].l,t[v].l,t[fa].l,t[faa].l,l,mid,k);
	else return query(t[u].r,t[v].r,t[fa].r,t[faa].r,mid+1,r,k-sum);
}
//void dfs1(int x,int fa,int dep){
//	f[x]=fa;
//	d[x]=dep;
//	size[x]=1;
//	change(rt[x],rt[fa],1,q,a[x],1);
//	int maxson=-1;
//	for(R int i=h[x],v;i;i=nx[i]){
//		v=ver[i];
//		if(v==fa)return;
//		dfs1(v,x,dep+1);
//		size[x]+=size[v];
//		if(size[v]>maxson)maxson=size[v],son[x]=v;
//	}
//}
//void dfs2(int x,int topp){
//	top[x]=topp;
//	if(!son[x])return;
//	dfs2(son[x],topp);
//	for(R int i=h[x],v;i;i=nx[i]){
//		v=ver[i];
//		if(v==f[x]||v==son[x])continue;
//		dfs2(v,v);
//	}
//}
//int lca(int x,int y){
//	while(top[x]!=top[y]){
//		if(d[top[x]]<d[top[y]])swap(x,y);
//		x=f[top[x]];
//	}
//	return d[x]<d[y]?x:y;
//}
queue<int>qq;
void bfs(){
	d[1]=1;qq.push(1);
	while(qq.size()){
		int x=qq.front();qq.pop();
		change(rt[x],rt[f[x][0]],1,q,a[x],1);
		for(int i=h[x];i;i=nx[i]){
			int v=ver[i];
			if(d[v])continue;
			d[v]=d[x]+1;
			qq.push(v);
			f[v][0]=x;
			for(int j=1;j<=19;j++){
				f[v][j]=f[f[v][j-1]][j-1];
			}
		}
	}
}
int lca(int u,int v){
	if(d[u]>d[v])swap(u,v);
	for(int i=19;i>=0;i--)
	if(d[u]<=d[f[v][i]])v=f[v][i];
	if(u==v)return u;
	for(int i=19;i>=0;i--)
	if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
	return f[u][0];
}
signed main(){
	n=read();m=read();
	for(R int i=1;i<=n;i++){
		a[i]=b[i]=read();
	}
	sort(b+1,b+n+1);
	q=unique(b+1,b+n+1)-b-1;
	for(R int i=1;i<=n;i++){
		a[i]=lower_bound(b+1,b+q+1,a[i])-b;
	}
	build(rt[0],1,q);
	for(R int i=1,u,v;i<n;i++){
		u=read();v=read();
		add(u,v);add(v,u);
	}
//	dfs1(1,0,1);dfs2(1,1);
	bfs();
	for(R int i=1,u,v,k,lca_uv;i<=m;i++){
		u=read();v=read();k=read();
		lca_uv=lca(u,v);
		printf("%lld\n",b[query(rt[u],rt[v],rt[lca_uv],rt[f[lca_uv][0]],1,q,k)]);
	}
	return 0;
}
2020/9/20 07:17
加载中...