zoukankan      html  css  js  c++  java
  • [Luogu 2486] SDOI2011 染色

    [Luogu 2486] SDOI2011 染色

    <题目链接>


    树剖水题,线段树维护。

    详细题解不写了。

    我只想说我写的线段树又变漂亮了qwq


    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    const int MAXN=100010;
    int n,m;
    class HLD
    {
    	private:
    		bool vis[MAXN];
    		int num;
    		static int rank[MAXN];
    		static struct Node
    		{
    			int v,depth,father,son,top,size,DFN;
    		}s[MAXN];
    		class SegmentTree
    		{
    			private:
    				struct Node
    				{
    					int v,left,right,lazy,color[2];
    					Node *c[2];
    					Node(int l,int r):left(l),right(r),lazy(0)
    					{
    						memset(color,0,sizeof color);
    						c[0]=c[1]=nullptr;
    						if(l==r)
    						{
    							v=1;
    							color[0]=color[1]=s[rank[l]].v;
    							return;
    						}
    						int mid=l+r>>1;
    						c[0]=new Node(l,mid);
    						c[1]=new Node(mid+1,r);
    						PushUp();
    					}
    					~Node(void)
    					{
    						if(c[0]!=nullptr)
    							delete c[0];
    						if(c[1]!=nullptr)
    							delete c[1];
    					}
    					void Modify(int x)
    					{
    						v=1;
    						lazy=color[0]=color[1]=x;
    					}
    					void PushUp(void)
    					{
    						v=c[0]->v+c[1]->v;
    						color[0]=c[0]->color[0];
    						color[1]=c[1]->color[1];
    						if(c[0]->color[1]==c[1]->color[0])
    							--v;
    					}
    					void PushDown(void)
    					{
    						if(c[0]!=nullptr)
    							c[0]->Modify(lazy);
    						if(c[1]!=nullptr)
    							c[1]->Modify(lazy);
    						lazy=0;
    					}
    					int Color(int x)
    					{
    						if(left==right)
    							return color[0];
    						if(lazy)
    							PushDown();
    						int mid=left+right>>1;
    						if(x>mid)
    							return c[1]->Color(x);
    						else
    							return c[0]->Color(x);
    					}
    					void Change(int l,int r,int v)
    					{
    						if(l==left && r==right)
    						{
    							Modify(v);
    							return;
    						}
    						if(lazy)
    							PushDown();
    						int mid=left+right>>1;
    						if(r<=mid)
    							c[0]->Change(l,r,v);
    						else if(l>mid)
    							c[1]->Change(l,r,v);
    						else
    						{
    							c[0]->Change(l,mid,v);
    							c[1]->Change(mid+1,r,v);
    						}
    						PushUp();
    					}
    					int Query(int l,int r)
    					{
    						if(l==left && r==right)
    							return v;
    						int mid=left+right>>1;
    						if(lazy)
    							PushDown();
    						if(r<=mid)
    							return c[0]->Query(l,r);
    						else if(l>mid)
    							return c[1]->Query(l,r);
    						else
    						{
    							int ans=c[0]->Query(l,mid)+c[1]->Query(mid+1,r);
    							if(c[0]->color[1]==c[1]->color[0])
    								--ans;
    							return ans;
    						}
    					}
    				}*root;
    			public:
    				SegmentTree(int n)
    				{
    					root=new Node(1,n);
    				}
    				~SegmentTree(void)
    				{
    					delete root;
    				}
    				int Color(int x)
    				{
    					return root->Color(x);
    				}
    				void Change(int l,int r,int v)
    				{
    					root->Change(l,r,v);
    				}
    				int Query(int l,int r)
    				{
    					return root->Query(l,r);
    				}
    		}*T;
    		struct Edge
    		{
    			int to;
    			Edge *next;
    			Edge(int to,Edge* next):to(to),next(next){}
    			~Edge(void)
    			{
    				if(next!=nullptr)
    					delete next;
    			}
    		}*head[MAXN];
    		void AddEdges(int u,int v)
    		{
    			head[u]=new Edge(v,head[u]);
    			head[v]=new Edge(u,head[v]);
    		}
    		void DFS1(int u,int k)
    		{
    			s[u].depth=k;
    			s[u].size=1;
    			int v;
    			for(Edge *i=head[u];i!=nullptr;i=i->next)
    				if(!s[v=i->to].size)
    				{
    					DFS1(v,k+1);
    					s[v].father=u;
    					s[u].size+=s[v].size;
    					if(s[v].size>s[s[u].son].size)
    						s[u].son=v;
    				}
    		}
    		void DFS2(int u,int top)
    		{
    			s[u].top=top;
    			s[u].DFN=++num;
    			rank[num]=u;
    			vis[u]=true;
    			if(s[u].son)
    				DFS2(s[u].son,top);
    			int v;
    			for(Edge *i=head[u];i!=nullptr;i=i->next)
    				if(!vis[v=i->to])
    					DFS2(v,v);
    		}
    	public:
    		HLD(int n):num(0)
    		{
    			memset(s,0,sizeof s);
    			std::fill(head+1,head+n+1,nullptr);
    			for(int i=1;i<=n;++i)
    				scanf("%d",&s[i].v);
    			for(int i=1,u,v;i<n;++i)
    			{
    				scanf("%d %d",&u,&v);
    				AddEdges(u,v);
    			}
    			DFS1(1,1);
    			DFS2(1,1);
    			T=new SegmentTree(n);
    		}
    		~HLD(void)
    		{
    			for(int i=1;i<=n;++i)
    				delete head[i];
    			delete T;
    		}
    		void Change(int x,int y)
    		{
    			int a,b,v;
    			scanf("%d",&v);
    			while((a=s[x].top)^(b=s[y].top))
    				if(s[a].depth>s[b].depth)
    				{
    					T->Change(s[a].DFN,s[x].DFN,v);
    					x=s[a].father;
    				}
    				else
    				{
    					T->Change(s[b].DFN,s[y].DFN,v);
    					y=s[b].father;
    				}
    			if(s[x].depth<s[y].depth)
    				T->Change(s[x].DFN,s[y].DFN,v);
    			else
    				T->Change(s[y].DFN,s[x].DFN,v);
    		}
    		void Query(int x,int y)
    		{
    			int a,b,ans=0;
    			while((a=s[x].top)^(b=s[y].top))
    				if(s[a].depth>s[b].depth)
    				{
    					ans+=T->Query(s[a].DFN,s[x].DFN);
    					x=s[a].father;
    					if(T->Color(s[a].DFN)==T->Color(s[x].DFN))
    						--ans;
    				}
    				else
    				{
    					ans+=T->Query(s[b].DFN,s[y].DFN);
    					y=s[b].father;
    					if(T->Color(s[b].DFN)==T->Color(s[y].DFN))
    						--ans;
    				}
    			ans+=s[x].depth<s[y].depth ? T->Query(s[x].DFN,s[y].DFN) : T->Query(s[y].DFN,s[x].DFN);
    			printf("%d
    ",ans);
    		}
    }*T;
    int HLD::rank[MAXN];
    HLD::Node HLD::s[MAXN];
    int main(int argc,char** argv)
    {
    	scanf("%d %d",&n,&m);
    	T=new HLD(n);
    	char c;
    	for(int i=1,x,y;i<=m;++i)
    	{
    		scanf("
    %c %d %d",&c,&x,&y);
    		if(c=='C')
    			T->Change(x,y);
    		else
    			T->Query(x,y);
    	}
    	delete T;
    	return 0;
    }
    

    谢谢阅读。

  • 相关阅读:
    POJ 2175 Evacuation Plan 费用流 负圈定理
    POJ 2983 Is the Information Reliable? 差分约束
    codeforces 420B Online Meeting
    POJ 3181 Dollar Dayz DP
    POJ Ant Counting DP
    POJ 1742 Coins DP 01背包
    中国儒学史
    产品思维30讲
    Java多线程编程核心技术
    编写高质量代码:改善Java程序的151个建议
  • 原文地址:https://www.cnblogs.com/Capella/p/9191205.html
Copyright © 2011-2022 走看看