轻重链剖分20ptsAC#1,8,12求助
查看原帖
轻重链剖分20ptsAC#1,8,12求助
359422
无咕_楼主2021/8/20 22:42

这题 LCA 就可以鬼知道我为啥要写树剖

//树剖做法
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAX=4e5+9;
struct Edge{
	int nxt,to;
}edge[MAX];
int num_edge=0,head[MAX];
struct Tree{
	int ls,rs;
	int maxn,tag;
}tree[MAX];
int num_tree=1;
int num_T=0,dep[MAX],f[MAX],top[MAX],Tid[MAX],siz[MAX],heavy[MAX];
int n,m;
void add_edge(int from,int to){
	edge[++num_edge]=(Edge){head[from],to};
	head[from]=num_edge;
}void push_up(int now){
	tree[now].maxn=max(tree[tree[now].ls].maxn,tree[tree[now].rs].maxn);
}void push_down(int now,int l,int r){
	int mid=(l+r)/2;
	tree[tree[now].ls].tag+=tree[now].tag;
	tree[tree[now].ls].maxn+=(mid-l+1)*tree[now].tag;
	tree[tree[now].rs].tag+=tree[now].tag;
	tree[tree[now].rs].maxn+=(r-mid)*tree[now].tag;
	tree[now].tag=0;
}void build(int now,int l,int r){
	if(l==r){
		tree[now].maxn=0;
		return;
	}int mid=(l+r)/2;
	tree[now].ls=++num_tree;
	tree[now].rs=++num_tree;
	build(tree[now].ls,l,mid);
	build(tree[now].rs,mid+1,r);
	push_up(now);
}void update(int now,int l,int r,int lx,int rx,int k){
	if(lx>r&&rx<l)return;
	if(lx<=l&&r<=rx){
		tree[now].maxn+=(r-l+1)*k;
		tree[now].tag+=k;
		return;
	}int mid=(l+r)/2;
	push_down(now,l,r);
	if(lx<=mid)update(tree[now].ls,l,mid,lx,rx,k);
	if(rx>mid)update(tree[now].rs,mid+1,r,lx,rx,k);
	push_up(now);
}int querymax(int now,int l,int r,int lx,int rx){
	if(lx>r&&rx<l)return -1;
	if(lx<=l&&r<=rx){
		return tree[now].maxn;
	}int mid=(l+r)/2,ans=-1;
	push_down(now,l,r);
	if(lx<=mid)ans=max(ans,querymax(tree[now].ls,l,mid,lx,rx));
	if(rx>mid)ans=max(ans,querymax(tree[now].rs,mid+1,r,lx,rx));
	return ans;
}void dfs1(int now,int fa){
	f[now]=fa;
	siz[now]=1;
	dep[now]=dep[fa]+1;
	for(int i=head[now];i;i=edge[i].nxt){
		int to=edge[i].to;
		if(to==fa)continue;
		dfs1(to,now);
		siz[now]+=siz[to];
		if(siz[to]>siz[heavy[now]])heavy[now]=to;
	}
}void dfs2(int now,int tp){
	top[now]=tp;
	Tid[now]=++num_T;
	if(heavy[now])dfs2(heavy[now],tp);
	for(int i=head[now];i;i=edge[i].nxt){
		int to=edge[i].to;
		if(to==f[now]||to==heavy[now])continue;
		dfs2(to,to);
	}
}void Tupdate(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		update(1,1,n,Tid[top[x]],Tid[x],1);
		x=f[top[x]];
	}if(dep[x]>dep[y])swap(x,y);
	update(1,1,n,Tid[x],Tid[y],1);
}
//int Tquerymax(int x,int y){
//	int ans=-1;
//	while(top[x]!=top[y]){
//		if(dep[top[x]]<dep[top[y]])swap(x,y);
//		ans=max(ans,querymax(1,1,n,Tid[top[x]],Tid[x]));
//		x=f[top[x]];
//	}if(dep[x]>dep[y])swap(x,y);
//	ans=max(ans,querymax(1,1,n,Tid[x],Tid[y]));
//	return ans;
//}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n-1;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		Tupdate(u,v); 
	}printf("%d\n",querymax(1,1,n,1,n));
	return 0;
} 

答案出错,不知道哪错了,求助qwq

2021/8/20 22:42
加载中...