WA 0pts 代码求调(LCA+线段树合并)
查看原帖
WA 0pts 代码求调(LCA+线段树合并)
545986
Jerrycyx楼主2023/6/7 18:36

RT,真的是服了

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

inline int read()
{
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*w;
}

const int N=100005;
const int INF=0x3f3f3f3f;
const int T=20;
int n,m;

int f[N][25],depth[N];
struct Allan{
	int to,nxt;
}edge[N<<1];
int edge_tot=0;
int head[N];
inline void edge_add(int from,int to)
{
	edge_tot++;
	edge[edge_tot].to=to;
	edge[edge_tot].nxt=head[from];
	head[from]=edge_tot;
	return;
}
queue<int> q;
void LCA_BFS()
{
	q.push(1),depth[1]=1;
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int i=head[x];i;i=edge[i].nxt)
		{
			int y=edge[i].to;
			if(depth[y]) continue;
			depth[y]=depth[x]+1;
			f[y][0]=x;
			for(int j=1;j<=T;j++)
				f[y][j]=f[f[y][j-1]][j-1];
			q.push(y);
		}
	}
	return;
}
int LCA(int x,int y)
{
	if(depth[x]>depth[y]) swap(x,y);
	for(int i=T;i>=0;i--)
		if(depth[f[y][i]]>=depth[x]) y=f[y][i];
	if(x==y) return x;
	for(int i=T;i>=0;i--)
		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	return f[x][0];
}


struct SegmetTree{
	int ls,rs;
	int dat,plc;
}tree[N<<6];
int tree_tot=0;
int root[N];
inline int build()
{
	tree_tot++;
	tree[tree_tot].ls=tree[tree_tot].rs=tree[tree_tot].dat=0;
	return tree_tot;
}
inline void update(int p)
{
	if(tree[tree[p].ls].dat>=tree[tree[p].rs].dat)
	{
		tree[p].dat=tree[tree[p].ls].dat;
		tree[p].plc=tree[p].ls;
	}
	else if(tree[tree[p].rs].dat>=0)
	{
		tree[p].dat=tree[tree[p].rs].dat;
		tree[p].plc=tree[p].rs;
	}
	return;
}
void tree_add(int p,int l,int r,int x,int y)
{
	if(l==r)
	{
		tree[p].dat+=y;
		tree[p].plc=x;
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid)
	{
		if(!tree[p].ls) tree[p].ls=build();
		tree_add(tree[p].ls,l,mid,x,y);
	}
	else
	{
		if(!tree[p].rs) tree[p].rs=build();
		tree_add(tree[p].rs,mid+1,r,x,y);
	}
	update(p);
	return;
}
int tree_merge(int p,int q,int l,int r)
{
	if(!p) return q;
	if(!q) return p;
	if(l==r){tree[p].dat+=tree[q].dat;return p;}
	int mid=(l+r)>>1;
	tree[p].ls=tree_merge(tree[p].ls,tree[q].ls,l,mid);
	tree[p].rs=tree_merge(tree[p].rs,tree[q].rs,mid+1,r);
	update(p);
	return p;
}

int maxz=0;

int ans[N];
void solve(int x)
{
	for(int i=head[x];i;i=edge[i].nxt)
	{
		int y=edge[i].to;
		if(y==f[x][0]) continue;
		solve(y);
		x=tree_merge(x,y,1,maxz);
	}
	ans[x]=tree[x].plc;
	if(tree[x].dat==0) ans[x]=0;
	return;
}

int xxx[N],yyy[N],zzz[N];
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n-1;i++)
	{
		int a=read(),b=read();
		edge_add(a,b),edge_add(b,a);
	}
	LCA_BFS();
	tree_tot=n;
	for(int i=1;i<=m;i++)
	{
		xxx[i]=read(),yyy[i]=read(),zzz[i]=read();
		maxz=max(maxz,zzz[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int t=LCA(xxx[i],yyy[i]);
		tree_add(xxx[i],1,maxz,zzz[i],1);
		tree_add(yyy[i],1,maxz,zzz[i],1);
		tree_add(t,1,maxz,zzz[i],-1);
		tree_add(f[t][0],1,maxz,zzz[i],-1);
	}
	solve(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}
2023/6/7 18:36
加载中...