萌新刚学OI,简单树剖求调(未过样例),悬赏1关注
查看原帖
萌新刚学OI,简单树剖求调(未过样例),悬赏1关注
719978
DYYqwq楼主2023/1/16 08:14

rt,疑似dfs2dfs2卡死了,但是本蒟蒻死活看不出来错在哪QAQ

#include<bits/stdc++.h>
#define lson(root) (root << 1)
#define rson(root) ((root << 1) | 1)
using namespace std;
struct edge
{
	int nxt , to;
}e[200010];
struct node
{
	int num , lc , rc , tag;
}tree[400010];
int n , m;
int a[100010];
int head[100010] , tot;
int dep[100010] , sz[100010] , son[100010] , fa[100010];
int dfn[100010] , cnt , rk[100010] , tp[100010];
void add(int u , int v)
{
	++ tot;
	e[tot].nxt = head[u];
	e[tot].to = v;
	head[u] = tot;
}
void dfs1(int u , int pa)
{
	dep[u] = dep[pa] + 1;
	sz[u] = 1;
	fa[u] = pa;
	for(int i = head[u] ; i != 0 ; i = e[i].nxt)
	{
		int v = e[i].to;
		if(v == pa)
			continue;
		sz[u] += sz[v];
		if(sz[son[u]] < sz[v])
			son[u] = v;
	}
}
void dfs2(int u , int tp_fa)
{
	dfn[u] = ++ cnt;
	rk[cnt] = u;
	tp[u] = tp_fa;
	if(son[u])
		dfs2(son[u] , tp_fa);
	for(int i = head[u] ; i != 0 ; i = e[i].nxt)
	{
		int v = e[i].to;
		if(fa[u] == v || v == son[u])
			continue;
		dfs2(v , v);
	}
}
void pushup(int root)
{ 
	tree[root].lc = tree[lson(root)].lc;
	tree[root].rc = tree[rson(root)].rc;
	int numm = tree[lson(root)].num + tree[rson(root)].num;
	if(tree[lson(root)].rc == tree[rson(root)].lc)
		numm --;
	tree[root].num = numm;
}
void pushdown(int root)
{
	if(tree[root].tag != 0)
	{
		tree[lson(root)].tag = tree[rson(root)].tag = tree[root].tag;
		tree[lson(root)].num = tree[rson(root)].num = 1;
		tree[lson(root)].lc = tree[lson(root)].rc = tree[root].lc;  
        tree[rson(root)].lc = tree[rson(root)].rc = tree[root].lc;  
		tree[root].tag = 0;  
	}
}
void update(int root , int l , int r , int L , int R , int x) // 直接替换!!!!! 
{
	if(L <= l && R >= r)
	{
		tree[root].num = 1;
		tree[root].tag = x;
        tree[root].lc = tree[root].rc = x;
        return;
	}
	pushdown(root);
	int mid = (l + r) >> 1;
	if(L <= mid)
		update(lson(root) , l , mid , L , R , x);
	if(R > mid)
		update(rson(root) , mid + 1 , r , L , R , x);
	pushup(root);
}
node query(int root , int l , int r , int L , int R)
{
	if(L <= l && R >= r)
		return tree[root];
	pushdown(root);
	int mid = (l + r) >> 1;
	node ans = {0 , 0 , 0 , -1} , ans2 , ans3;
	if(L <= mid)
	{
		ans2 = query(lson(root) , l , mid , L , R);
		ans.num += ans2.num; 
	}
	if(R > mid)
	{
		ans3 = query(rson(root) , mid + 1 , r , L , R);
		ans.num += ans2.num;
	}
	if(tree[lson(root)].rc == tree[rson(root)].lc)
		ans.num --;
	ans.lc = ans2.lc;
	if(ans.lc == 0)
		ans.lc = ans3.lc;
	ans.rc = ans3.rc;
	if(ans.rc == 0)
		ans.rc = ans2.rc;
	return ans;
}
void build(int root , int l , int r)
{
	tree[root].tag = 0;
	if(l == r)
	{
		tree[root].num = 1;
		// tree[root].lc =  ???????????
		tree[root].lc = tree[root].rc = a[rk[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(lson(root) , l , mid);
	build(rson(root) , mid + 1 , r);
	pushup(root);
}
void uv_update(int u , int v , int x)
{
	while(tp[u] != tp[v])
	{
		if(dep[tp[u]] < dep[tp[v]])
			swap(u , v);
		update(1 , 1 , n , dfn[tp[u]] , dfn[u] , x);
		u = fa[tp[u]];
	}
	if(dep[u] < dep[v])
		swap(u , v);
	update(1 , 1 , n , dfn[v] , dfn[u] , x);
}
node uv_query(int u , int v)
{
	node ans;
	node now , last1 = {0 , -1 , -1} , last2 = {0 , -1 , -1};
	while(tp[u] != tp[v])
	{
		if(dep[tp[u]] < dep[tp[v]])
		{
			swap(u , v);
			swap(last1 , last2);
		}
		now = query(1 , 1 , n , dfn[tp[u]] , dfn[u]);
		last1.num += now.num;
		if(last1.lc == now.rc)
			last1.num --;
		u = fa[tp[u]];
	}
	if(dep[u] < dep[v])
	{
		swap(u , v);
		swap(last1 , last2);
	}
	node QAQ = query(1 , 1 , n , dfn[v] , dfn[u]);
	ans.num += QAQ.num;
	if(QAQ.lc == last1.lc)
        ans.num --;
    if(QAQ.rc == last2.lc)
        ans.num --;
	return ans;
}
int main()
{
	scanf("%d%d" , &n , &m);
	for(int i = 1 ; i <= n ; i ++)
		scanf("%d" , &a[i]);
	for(int i = 1 ; i < n ; i ++)
	{
		int u , v;
		scanf("%d%d" , &u , &v);
		add(u , v);
		add(v , u);
	}
	dfs1(1 , 0);
	// printf("dfs1 OK\n");
	dfs2(1 , 1);
	// printf("dfs2 OK\n");
	build(1 , 1 , n);
	// printf("build OK\n");
	while(m --)
	{
		char op;
		cin >> op;
		if(op == 'C')
		{
			int u , v , w;
			scanf("%d%d%d" , &u , &v , &w);
			uv_update(u , v , w);
		}
		if(op == 'Q')
		{
			int u , v;
			printf("%d\n" , uv_query(u , v));
		}
	}
	return 0;
}
2023/1/16 08:14
加载中...