萌新求助 树剖全WA
查看原帖
萌新求助 树剖全WA
352352
artalter楼主2022/1/4 10:25
#include<cstdio>
#include<iostream>
#include<cctype>
using namespace std;
//常用函数
const int MAXN=1e5+10;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
#define t tree[pos]
#define tl tree[ls(pos)]
#define tr tree[rs(pos)]
//结构体
struct edge
{
	int nxt,v;
}e[2*MAXN];
struct lineCutTree
{
	int l,r;
	int leftColour,RightColour,colourNumber,lazyColour;
}tree[4*MAXN];
//定义
int n,m;
int head[2*MAXN],a[MAXN],f[MAXN],size[MAXN],dep[MAXN],son[MAXN],rk[MAXN],id[MAXN],cnt,num,top[MAXN];
void add(int u,int v)
{
	cnt++;
	e[cnt].v = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}
//树链剖分
void dfs1(int u,int fa)
{	
	dep[u] = dep[fa]+1;
	size[u] = 1;
	f[u] = fa;
	for(int i = head[u]; i ; i= e[i].nxt)
	{
		int v = e[i].v;
		if(v == fa)continue;
		dfs1(v,u);
		size[u] += size[v];
		if(size[v] > size[son[u]] || !son[u])
		{
			son[u] = v;
		}
	}
}
void dfs2(int u,int fa,int tp)
{
	num++;
	id[u] = num;
	rk[num] = u;
	top[u] = tp;
	if(!son[u])return;
	dfs2(son[u],u,tp);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v = e[i].v;
		if(v == son[u] || v==fa) continue;
		dfs2(v,u,v);
	}
}
//线段树
void build(int pos,int l,int r);
lineCutTree query(int pos,int l,int r);
void change(int pos,int l,int r,int w);
void update(int pos);
//lca
int find(int x,int y)
{
	int ret=0;
	int pos1=0,pos2=0;
	int fx=top[x],fy=top[y];
	while(fx != fy)
	{
		if(dep[fx] > dep[fy])
		{
			lineCutTree temp = query(1,id[fx],id[x]);
			ret += temp.colourNumber;
			if(temp.RightColour == pos1) ret--;
			pos1 = temp.leftColour;
			x = f[fx];
			fx = top[x];
		}else 
		{
			lineCutTree temp =query(1,id[fy],id[y]);
			ret += temp.colourNumber;
			if(temp.RightColour == pos2)ret--;
			pos2 = temp.leftColour;
			y = f[fy];
			fy = top[y];
		}
	}
	if(id[x] > id[y])
	{
		swap(x,y);
		swap(pos1,pos2);
	}
	lineCutTree temp = query(1,id[x],id[y]);
	ret += temp.colourNumber;
	if(temp.leftColour == pos1) ret--;
	if(temp.RightColour == pos2)ret--;
	return ret;
}
void update(int x,int y,int w)
{
	int fx=top[x],fy=top[y];
	while(fx != fy)
	{
		if(dep[fx] > dep[fy])
		{
			change(1,id[fx],id[x],w);
			x = f[fx];
			fx = top[x];
		}else 
		{
			change(1,id[fy],id[y],w);
			y = f[fy];
			fy = top[y];
		}
	}
	if(id[x] > id[y])swap(x,y);

	change(1,id[x],id[y],w);
}
//运行
void solve();
int main()
{
	solve();
	return 0;
}
//函数 运行
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);add(v,u);
	}
	dfs1(1,0);
	dfs2(1,0,1);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		char op;
		cin>>op;
		if(op=='C')
		{
			int a,b,c;
			cin>>a>>b>>c;
			update(a,b,c);
		}else if(op=='Q')
		{
			int a,b;
			cin>>a>>b;
			cout<<find(a,b)<<endl;
		}
	}
}

void build(int pos,int l,int r)
{
	int mid = (l+r) >> 1;
	tree[pos].l=l;
	tree[pos].r=r;
	if(tree[pos].l==tree[pos].r)
	{
		tree[pos].leftColour = tree[pos].RightColour = a[rk[mid]];
		tree[pos].colourNumber = 1;
		return;
	}
	build(ls(pos),l,mid);
	build(rs(pos),mid+1,r);
	tree[pos].colourNumber = tree[ls(pos)].colourNumber + tree[rs(pos)].colourNumber;
	tree[pos].leftColour = tree[ls(pos)].leftColour;
	tree[pos].RightColour = tree[rs(pos)].RightColour;
	if(tree[ls(pos)].RightColour == tree[rs(pos)].leftColour)
	{
		tree[pos].colourNumber --;
	}
}
void change(int pos,int l,int r,int w)
{
	int mid = (tree[pos].l + tree[pos].r) >> 1;
	if(tree[pos].l >= l && tree[pos].r <= r)
	{
		tree[pos].lazyColour = w;
		tree[pos].leftColour = w;
		tree[pos].RightColour = w;
		tree[pos].colourNumber = 1;
		return;
	}
	update(pos);
	if(l <= mid)
	{
		change(ls(pos),l,r,w);
	}
	if(r > mid)
	{
		change(rs(pos),l,r,w);
	}
	tree[pos].colourNumber = tree[ls(pos)].colourNumber + tree[rs(pos)].colourNumber;
	tree[pos].leftColour = tree[ls(pos)].leftColour;
	tree[pos].RightColour = tree[rs(pos)].RightColour;
	if(tree[ls(pos)].RightColour == tree[rs(pos)].leftColour)
	{
		tree[pos].colourNumber -- ;
	}
}
void update(int pos)
{
	if(tree[pos].lazyColour)
	{
		tree[ls(pos)].leftColour = tree[pos].lazyColour;
		tree[ls(pos)].RightColour = tree[pos].lazyColour;
		tree[ls(pos)].colourNumber = 1;
		tree[rs(pos)].leftColour = tree[pos].lazyColour;
		tree[rs(pos)].RightColour = tree[pos].lazyColour;
		tree[rs(pos)].colourNumber = 1;
	}
	if(tree[pos].l != tree[pos].r)
	{
		tree[ls(pos)].lazyColour = tree[pos].lazyColour;
		tree[rs(pos)].lazyColour = tree[pos].lazyColour;
	}
	tree[pos].lazyColour = 0;
}

lineCutTree query(int pos ,int l ,int r)
{	
	int mid = ( tree[pos].l + tree[pos].r ) >> 1;
	if(tree[pos].l >= l && tree[pos].r <= r)
	{
		return t;
	}
	update(pos);
	lineCutTree temp,tempLeft,tempRight;
	temp.leftColour = 0;
	temp.RightColour = 0;
	temp.colourNumber = 0;
	if(l <= mid)
	{
		tempLeft = query (ls(pos) , l , r);
		temp.leftColour = tempLeft.leftColour;
		temp.colourNumber += tempLeft.colourNumber;
	}
	if(r > mid)
	{
		tempRight = query (rs(pos) , l , r);
		temp.RightColour = tempRight.RightColour;
		temp.colourNumber += tempRight.colourNumber;
	}
	if(!temp.leftColour) return tempRight;
	if(!temp.RightColour) return tempLeft;
	if(tempLeft.RightColour == tempRight.leftColour)temp.colourNumber --;
	return temp;
}

WA自动机

2022/1/4 10:25
加载中...