求助
  • 板块灌水区
  • 楼主FLAT_LCH
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/10/20 10:23
  • 上次更新2023/11/4 03:12:24
查看原帖
求助
180924
FLAT_LCH楼主2021/10/20 10:23

P2486 [SDOI2011]染色 WA了,只有35

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>

using namespace std;

struct bian
{
	int v,nex;
}side[900000];
struct nodee
{
	int l,r,lc,rc,summ,add;
}tre[900000];
struct node
{
	int pos,head,f,dep,size,son,top,c;
}p[900000];

int c[900000],n,m,len=0;

inline void xiachuan(int w)
{
	if(tre[w].add==-1)return;
	tre[w*2].lc=tre[w].add;tre[w*2].rc=tre[w].add;
	tre[w*2+1].lc=tre[w].add;tre[w*2+1].rc=tre[w].add;
	tre[w*2].add=tre[w].add;tre[w*2+1].add=tre[w].add;
	tre[w*2].summ=1;tre[w*2+1].summ=1;
	tre[w].add=-1;
}

void build(int w,int l,int r)
{
	tre[w].l=l;tre[w].r=r;tre[w].add=-1;
	if(tre[w].l==tre[w].r){tre[w].summ=1;tre[w].lc=c[l];tre[w].rc=c[l];return;}
	build(w*2,l,(l+r)/2);build(w*2+1,(l+r)/2+1,r);
	tre[w].lc=tre[w*2].lc;tre[w].rc=tre[w*2+1].rc;tre[w].summ=tre[w*2].summ+tre[w*2+1].summ;
	if(tre[w*2].rc==tre[w*2+1].lc)tre[w].summ--;
}
inline void Build(){build(1,1,n);}

void Changee(int w,int l,int r,int s)
{
	if(tre[w].l>r||tre[w].r<l)return;
	if(tre[w].l>=l&&tre[w].r<=r){tre[w].add=s;tre[w].lc=s;tre[w].rc=s;tre[w].summ=1;return;}
	xiachuan(w);
	Changee(w*2,l,r,s);Changee(w*2+1,l,r,s);
	tre[w].lc=tre[w*2].lc;tre[w].rc=tre[w*2+1].rc;tre[w].summ=tre[w*2].summ+tre[w*2+1].summ;
	if(tre[w*2].rc==tre[w*2+1].lc)tre[w].summ--;
}
inline void Change(int l,int r,int s){Changee(1,min(l,r),max(l,r),s);}
inline void change(int x,int y,int s)
{
	int fx=p[x].top,fy=p[y].top;
	while(fx!=fy)
	{
		if(p[fx].dep<p[fy].top)
		{
			swap(x,y);
			swap(fx,fy);
		}
		Change(p[x].pos,p[fx].pos,s);
		x=p[fx].f;fx=p[x].top;
	}
	Change(p[x].pos,p[y].pos,s);
}

int Getcc(int w,int k)
{
	if(tre[w].l==tre[w].r)return tre[w].lc;
	xiachuan(w);
	if(tre[w*2].r>=k&&tre[w*2].l<=k)return Getcc(w*2,k);
	return Getcc(w*2+1,k);
}
inline int Getc(int k){return Getcc(1,k);}
inline int getcc(int w){return Getc(p[w].pos);}

int Getsumm(int w,int l,int r)
{
	if(tre[w].l>r||tre[w].r<l)return 0;
	if(tre[w].l>=l&&tre[w].r<=r)return tre[w].summ;
	xiachuan(w);
	int a=Getsumm(w*2,l,r),b=Getsumm(w*2+1,l,r);
	if(a!=0&&b!=0&&Getc(tre[w*2].r)==Getc(tre[w*2+1].l))return a+b-1;
	return a+b;
}
inline int Getsum(int l,int r){return Getsumm(1,min(l,r),max(l,r));}
inline int getsum(int x,int y)
{
	int summ=0;
	int fx=p[x].top,fy=p[y].top;
	while(fx!=fy)
	{
		if(p[fx].dep<p[fy].top)
		{
			swap(x,y);
			swap(fx,fy);
		}
		summ+=Getsum(p[x].pos,p[fx].pos);
		if(getcc(fx)==getcc(p[fx].f))summ--;
		//cout<<fx<<' '<<p[fx].f<<' '<<getcc(fx)<<' '<<getcc(p[fx].f)<<endl;
		//getcc(fx);
		x=p[fx].f;fx=p[x].top;
	}
	//if(getcc(x)==getcc(y))summ--;
	summ+=Getsum(p[x].pos,p[y].pos);
	return summ;
}

inline void lian(int u,int v)
{
	len++;side[len].v=v;side[len].nex=p[u].head;p[u].head=len;
	len++;side[len].v=u;side[len].nex=p[v].head;p[v].head=len;
}

inline void readd()
{
	len=0;
	int u,v;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>p[i].c;
	for(int i=1;i<n;i++)
	{
		cin>>u>>v;
		lian(u,v);
	}
	p[1].dep=1;
	p[1].f=0;
	p[0].c=-1;
	len=0;
}

void dfs1(int w)
{
	p[w].size=1;p[w].son=-1;
	p[w].top=w;
	
	int v;
	for(int i=p[w].head;i!=0;i=side[i].nex)
	{
		v=side[i].v;
		if(v!=p[w].f)
		{
			p[v].f=w;p[v].dep=p[w].dep+1;
			dfs1(v);
			p[w].size+=p[v].size;
			if(p[w].son==-1||p[v].size>p[p[w].son].size)p[w].son=v;
		}
	}
}

void dfs2(int w)
{
	len++;
	p[w].pos=len;
	c[len]=p[w].c;
	if(p[w].son!=-1)
	{
		p[p[w].son].top=p[w].top;
		dfs2(p[w].son);
	}
	
	int v;
	for(int i=p[w].head;i!=0;i=side[i].nex)
	{
		v=side[i].v;
		if(v!=p[w].f&&v!=p[w].son)
		{
			dfs2(v);
		}
	}
	
}

inline void working()
{
	char f;int x,y,z;
	for(int i=1;i<=m;i++)
	{
		//cout<<i<<','<<endl;
		cin>>f;
		if(f=='C')
		{
			cin>>x>>y>>z;
			change(x,y,z);
		}
		else
		{
			cin>>x>>y;
			///cout<<x<<' '<<y<<' ';
			cout<<getsum(x,y)<<endl;
		}
	}
}

int main()
{
	readd();
	dfs1(1);
	dfs2(1);
	Build();
	//cout<<endl;for(int i=1;i<=n;i++)cout<<i<<' '<<p[i].pos<<endl;
	working();
	return 0;
}

我知道这里写getcc很浪费运行时间,但是反正也不会TLE,码量思考量也小,很适合我这个萌新

2021/10/20 10:23
加载中...