bzoj2243: [SDOI2011]染色

好吧本来看到就是一道裸地树剖嘛。。然后差错差了一个晚上。。发现时线段树下传标记的时候坑了

连线段树都打不来了QAQ


计算答案的时候需要注意一下其他什么都好说

突然发现其实我的程序还是很好看的(误


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char c;
inline void read(int &a)
{
	a=0;do 
	{
	c=getchar();
	}while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

struct Data
{
	int l_c,r_c;
	int D;
	inline friend Data operator +(Data a,Data b)
	{
		Data c;
		if(a.D==-1)return b;
		if(b.D==-1)return a;
		c.D=(a.r_c==b.l_c)?(a.D+b.D-1):(a.D+b.D);
	    c.l_c=a.l_c;
	    c.r_c=b.r_c;
	    return c;
	}
};
inline Data rev(Data a)
{
	return (Data){a.r_c,a.l_c,a.D};
}
int Color[200001];
int Heavy_Chain_Node[200001],Heavy_Chain_Place[200001],Heavy_Chain_Begin[200001],Heavy_Chain_End[200001];
int Size[200001],Heavy_Son[200001],F[200001];
int Deep[200001];
int Con;
struct Chain{int u;Chain *next;Chain(){next=NULL;}}*Head[200001];
inline void addside(int a,int b)
{
	Chain *tp=new Chain;
    tp->next=Head[a];
    tp->u=b;
    Head[a]=tp;
}

void DFS(int u,int fa)
{
	Size[u]++;
	F[u]=fa;
	Heavy_Son[u]=0;
	for(Chain *tp=Head[u];tp;tp=tp->next)
	  if(tp->u!=fa)
	     {
	     	Deep[tp->u]=Deep[u]+1;
	     	DFS(tp->u,F[tp->u]=u);
	     	Size[u]+=Size[tp->u];
	     	if(Size[Heavy_Son[u]]<Size[tp->u])
	     	   Heavy_Son[u]=tp->u;
		 }
}

void DFS2(int u,int Begin,int fa)
{
	Heavy_Chain_Begin[u]=Begin;
	Heavy_Chain_Place[u]=++Con;
	Heavy_Chain_Node[Con]=u;
	if(Heavy_Son[u])
	   DFS2(Heavy_Son[u],Begin,u);
	Heavy_Chain_End[u]=Con;
	for(Chain *tp=Head[u];tp;tp=tp->next)
	  if(tp->u!=Heavy_Son[u]&&tp->u!=fa)
	    DFS2(tp->u,Con+1,u);

}
struct Segement
{
     int l,r;
     Data D;
     bool lazy;
}Segement_Tree[500001];
void Segement_Build(int place,int l,int r)
{
	Segement_Tree[place].l=l;
	Segement_Tree[place].r=r;
	Segement_Tree[place].lazy=false;
	if(l^r)
	{
		Segement_Build(place<<1,l,(l+r)>>1);
		Segement_Build(place<<1|1,((l+r)>>1)+1,r);
		Segement_Tree[place].D=Segement_Tree[place<<1].D+Segement_Tree[place<<1|1].D;
	    return ;
	}
	else 
		Segement_Tree[place].D=(Data){Color[Heavy_Chain_Node[l]],Color[Heavy_Chain_Node[l]],1};
}
inline void pushdown(int place)
{
	Segement_Tree[place<<1].D=
	Segement_Tree[place<<1|1].D=
	Segement_Tree[place].D;
	Segement_Tree[place<<1|1].lazy=
	Segement_Tree[place<<1].lazy=true;
	Segement_Tree[place].lazy=false;
}

inline void Segement_Modify(int place,int l,int r,Data D)
{
  if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r)
     {
     	Segement_Tree[place].D=D;
     	Segement_Tree[place].lazy=true;
     	return ;
	 }		
	 	if(Segement_Tree[place].l^Segement_Tree[place].r)
	    	if(Segement_Tree[place].lazy)
	           pushdown(place);
	if(l<=Segement_Tree[place<<1].r)
	  Segement_Modify(place<<1,l,r,D);
        if(r>=Segement_Tree[place<<1|1].l)
	  Segement_Modify(place<<1|1,l,r,D);   
	Segement_Tree[place].D=Segement_Tree[place<<1].D+Segement_Tree[place<<1|1].D;
	Segement_Tree[place].lazy=false;
}

Data Segement_Query(int place,int l,int r)
{
	if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r)
	   return Segement_Tree[place].D;
	
	if(Segement_Tree[place].l^Segement_Tree[place].r)
	    	if(Segement_Tree[place].lazy)
	           pushdown(place);
	Data res;
	res.D=-1;
	if(l<=Segement_Tree[place<<1].r)
	  res=Segement_Query(place<<1,l,r);
        if(r>=Segement_Tree[place<<1|1].l)
	  res=res+Segement_Query(place<<1|1,l,r);   
    return res;
}

inline Data Query(int x,int y)
{
	Data xx,yy;
    xx.D=yy.D=-1;
    while(Heavy_Chain_Begin[x]^Heavy_Chain_Begin[y])
    {
    	if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>=Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]])
          xx=Segement_Query(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x])+xx,x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]];
	    else
	      yy=Segement_Query(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y])+yy,y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]];
	}
	if(Deep[x]<=Deep[y])
	    return rev(xx)+Segement_Query(1,Heavy_Chain_Place[x],Heavy_Chain_Place[y])+yy; 
	return rev(yy)+Segement_Query(1,Heavy_Chain_Place[y],Heavy_Chain_Place[x])+xx;
}
inline void Modify(int x,int y,int c)
{
	Data D;
    D.l_c=D.r_c=c;
    D.D=1;
	while(Heavy_Chain_Begin[x]^Heavy_Chain_Begin[y])
    {
    	if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>=Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]])
          Segement_Modify(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x],D),x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]];
	    else
	      Segement_Modify(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y],D),y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]];
	}
	if(Deep[x]<=Deep[y])
	    Segement_Modify(1,Heavy_Chain_Place[x],Heavy_Chain_Place[y],D); 
	Segement_Modify(1,Heavy_Chain_Place[y],Heavy_Chain_Place[x],D);
}

int main()
{
	int n,m,i,j,k;
	read(n),read(m);
	for(i=1;i<=n;i++)
	   read(Color[i]);
	for(i=1;i<n;i++)read(j),read(k),addside(j,k),addside(k,j);
	DFS(1,1);
	DFS2(1,1,1);
	Segement_Build(1,1,Con);
	int a,b,c;	
	char ch;
	while(m--)
	 {
	 	do ch=getchar();while(ch!='Q'&&ch!='C');
	 	if(ch=='C')
		 {
		   read(a),read(b),read(c);
		   Modify(a,b,c);
		  }
	 	else 
		 {
		 	read(a),read(b);
		 	printf("%d\n",Query(a,b).D);
		 }
	 }
	return 0;
}


你可能感兴趣的:(bzoj)