逆天UB发问
查看原帖
逆天UB发问
760171
Binah_cyc楼主2024/8/12 21:54
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define push_back emplace_back
const int N=1e5+5;
int n,m,sum[N];
int head[N],tot;
struct Node
{
	int nxt,to;
} edge[N<<1];
void add(int u,int v)
{
	edge[++tot]=Node {head[u],v},head[u]=tot;
}

int fa[N],deep[N],son[N],sze[N];
void dfs1(int now,int f,int dep)
{
	fa[now]=f,deep[now]=dep,sze[now]=1;
	for(int i=head[now]; i; i=edge[i].nxt)
	{
		if(edge[i].to!=f)
		{
			dfs1(edge[i].to,now,dep+1),sze[now]+=sze[edge[i].to];
			if(sze[son[now]]<sze[edge[i].to]) son[now]=edge[i].to;
		}
	}
}
int cnt,id[N],top[N],a[N];
void dfs2(int now,int ffa)
{
	top[now]=ffa,id[now]=++cnt,a[cnt]=sum[now];
	if(son[now]) dfs2(son[now],ffa);
	for(int i=head[now]; i; i=edge[i].nxt)
		if(edge[i].to!=fa[now]&&edge[i].to!=son[now])
			dfs2(edge[i].to,edge[i].to);
}

struct SegmentTree
{
	int l,r;
	int sum,flag;
	int lcolor,rcolor;
} t[N<<2];
void spread(int p)
{
	if(t[p].flag)
	{
		t[p*2].sum=t[p*2+1].sum=1;
		t[p*2].flag=t[p*2+1].flag=t[p].flag;
		t[p*2].lcolor=t[p].flag,t[p*2].rcolor=t[p].flag;
		t[p*2+1].lcolor=t[p*2+1].rcolor=t[p].flag;
		t[p].flag=0;
	}
}
SegmentTree operator+(SegmentTree a,SegmentTree b)
{
	SegmentTree c;
	c.l=a.l,c.r=b.r;
	c.lcolor=a.lcolor,c.rcolor=b.rcolor;
	c.sum=a.sum+b.sum;
	if(a.rcolor==b.lcolor) c.sum--;
	return c;
}
void build(int l,int r,int p)
{
	t[p].l=l,t[p].r=r;
	if(l==r) return (void)(t[p].sum=1,t[p].lcolor=t[p].rcolor=a[l]);
	int mid=(l+r)>>1;
	build(l,mid,p*2),build(mid+1,r,p*2+1);
	t[p]=t[p*2]+t[p*2+1];
}
void change(int l,int r,int p,int k)
{
	if(l<=t[p].l&&t[p].r<=r) return (void)(t[p].sum=1,t[p].flag=t[p].lcolor=t[p].rcolor=k);
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change(l,r,p*2,k);
	if(r>mid)  change(l,r,p*2+1,k);
	t[p]=t[p*2]+t[p*2+1];
}
SegmentTree ask(int l,int r,int p)
{
	if(l<=t[p].l&&t[p].r<=r) return t[p];
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid&&r>mid) return ask(l,r,p*2)+ask(l,r,p*2+1);
	else if(l<=mid)   return ask(l,r,p*2);
	else if(r>mid)    return ask(l,r,p*2+1);
}
void changeroad(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		change(id[top[x]],id[x],1,k),x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	change(id[x],id[y],1,k);
}
int askroad(int x,int y)
{
	int cnt=0;
	SegmentTree now;
	int ans1=INT_MIN,ans2=INT_MIN;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y),swap(ans1,ans2);
		now=ask(id[top[x]],id[x],1);
		cnt+=now.sum-(ans1==now.rcolor),ans1=now.lcolor;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y),swap(ans1,ans2);
	now=ask(id[x],id[y],1);
	cnt+=now.sum-(ans1==now.lcolor)-(ans2==now.rcolor);
	return cnt;
}
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1; i<=n; i++) cin>>sum[i];
	for(int i=1,x,y; i<n; i++) cin>>x>>y,add(x,y),add(y,x);
	dfs1(1,-1,1),dfs2(1,1),build(1,n,1);
	while(m--)
	{
		string op;
		int x,y,k;
		cin>>op;
		if(op=="C") cin>>x>>y>>k,changeroad(x,y,k);
		else cin>>x>>y,cout<<askroad(x,y)<<'\n';
	}
	return 0;
}
  1. 我本地编译器和洛谷IDE上的答案不一样
  2. 为什么把 num 和 flag 的数据类型改成 long long 就会得出奇怪的答案
2024/8/12 21:54
加载中...