树剖求助
查看原帖
树剖求助
228843
wangjinbo楼主2020/5/3 12:07

55分,#12~#20WA,去Loj上交了一下发现基本都是比答案大1,调不出来了,帮忙调一下吧谢谢

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct edge{
	int next,to;
}a[maxn<<1];
int head[maxn],cnt;
void add(int x,int y)
{
	a[++cnt].next=head[x];
	a[cnt].to=y;
	head[x]=cnt;
}
int size[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn],seg[maxn],c[maxn],col[maxn],dfstime;
struct segtree{
	int cnt,coll,colr;
}t[maxn<<2];
int Lc,Rc,n,m;
void pushup(int p)
{
	t[p].cnt=t[p<<1].cnt+t[p<<1|1].cnt;
	t[p].coll=t[p<<1].coll;t[p].colr=t[p<<1|1].colr;
	if(t[p<<1].colr==t[p<<1|1].coll)t[p].cnt--;
}
void build(int l,int r,int p)
{
	if(l==r){
		t[p].cnt=1;
		t[p].coll=t[p].colr=col[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1); 
	pushup(p);
}
void dfs1(int now,int f)
{
	size[now]=1;
	fa[now]=f;
	dep[now]=dep[f]+1;
	for(int i=head[now];i;i=a[i].next)
	{
		int u=a[i].to;
		if(u==f)continue;
		dfs1(u,now);
		size[now]+=size[u];
		if(size[u]>size[son[now]])son[now]=u;
	}
}
void dfs2(int now,int topf)
{
	seg[now]=++dfstime;
	top[now]=topf;
	if(!son[now])return;
	dfs2(son[now],topf);
	for(int i=head[now];i;i=a[i].next)
	{
		int u=a[i].to;
		if(u==fa[now]||u==son[now])continue;
		dfs2(u,u);
	}
}
void pushdown(int p)
{
	t[p<<1].cnt=t[p<<1|1].cnt=1;
	t[p<<1].coll=t[p<<1|1].coll=t[p<<1].colr=t[p<<1|1].colr=t[p].coll;
}
void update(int l,int r,int x,int y,int k,int p)
{
	if(x<=l&&r<=y){
		t[p].cnt=1;
		t[p].coll=t[p].colr=k;
		return;
	}
	if(t[p].cnt==1)pushdown(p);
	int mid=(l+r)>>1;
	if(x<=mid)update(l,mid,x,y,k,p<<1);
	if(mid<y)update(mid+1,r,x,y,k,p<<1|1);
	pushup(p);
}
int query(int l,int r,int x,int y,int p)
{
	if(x<=l&&r<=y){
		if(l==x)Lc=t[p].coll;
		if(r==y)Rc=t[p].colr;
		return t[p].cnt;
	}
	if(t[p].cnt==1)pushdown(p);
	int mid=(l+r)>>1,res=0;
	bool flag=1;
	if(x<=mid)res+=query(l,mid,x,y,p<<1);else flag=0;
	if(mid<y)res+=query(mid+1,r,x,y,p<<1|1);else flag=0;
	if(flag&&t[p<<1].colr==t[p<<1|1].coll)res--;
	return res; 
}
void solve1(int x,int y,int z)
{
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		update(1,n,seg[top[x]],seg[x],z,1);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	update(1,n,seg[x],seg[y],z,1);
} 
int solve2(int x,int y)
{
	int ans1=-1,ans2=-1;
	int res=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y),swap(ans1,ans2);
		res+=query(1,n,seg[top[x]],seg[x],1);
		if(Rc==ans1)res--;
		ans1=Lc;
		x=fa[top[x]];
	}
	bool flag=0;
	if(dep[x]>dep[y])swap(x,y),swap(ans1,ans2),flag=1;
	res+=query(1,n,seg[x],seg[y],1);
	if(flag){
	    if(Rc==ans1)res--;
	    if(Lc==ans2)res--;
	}
	else{
		if(Lc==ans1)res--;
	    if(Rc==ans2)res--;
	}
	return res;
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%d",&c[i]);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x); 
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=1;i<=n;i++)
	col[seg[i]]=c[i];
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		getchar();getchar();
		char c=getchar();
		if(c=='C'){
			int x,y,z;
			scanf("%d %d %d",&x,&y,&z);
			solve1(x,y,z);
		}
		else{
			int x,y;
			scanf("%d %d",&x,&y);
			printf("%d\n",solve2(x,y)); 
		}
	}
	return 0;
}

还有就是读入换行符要写几个getchar()啊,本地是1个,这道题交的时候要2个,但洛谷上有些题是1个

2020/5/3 12:07
加载中...