zoukankan      html  css  js  c++  java
  • SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree

    【题目分析】

        QTREE2,一看是倍增算法,太懒了,不写了。( ̄_, ̄ )

        QTREE3,树链剖分可以做,发现链上的问题LCT也很好做。

        要是子树问题貌似可以DFS序。

        然后就成LCT模板题了。

        考前背板模式开启了。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define maxn 100005
    
    struct LCT{
    	int ch[maxn][2],fa[maxn],sta[maxn],top,rev[maxn],mx[maxn],col[maxn];
    	bool isroot(int x)
    	{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    	void update(int x)
    	{
    		if (~mx[ch[x][0]]) mx[x]=mx[ch[x][0]];
    		else if (col[x]) mx[x]=x;
    		else if (~mx[ch[x][1]]) mx[x]=mx[ch[x][1]];
    		else mx[x]=-1;
    	}
    	void pushdown(int x)
    	{
    		if (rev[x])
    		{
    			rev[x]^=1;
    			rev[ch[x][0]]^=1;
    			rev[ch[x][1]]^=1;
    			swap(ch[x][0],ch[x][1]);
    		}
    	}
    	void rot(int x)
    	{
    		int y=fa[x],z=fa[y],l,r;
    		if (ch[y][0]==x) l=0; else l=1;
    		r=l^1;
    		if (!isroot(y))
    		{
    			if (ch[z][0]==y) ch[z][0]=x;
    			else ch[z][1]=x;
    		}
    		fa[x]=z; fa[y]=x; fa[ch[x][r]]=y;
    		ch[y][l]=ch[x][r]; ch[x][r]=y;
    		update(y);update(x);
    	}
    	void splay(int x)
    	{
    		top=0;sta[++top]=x;
    		for (int i=x;!isroot(i);i=fa[i]) sta[++top]=fa[i];
    		while (top) pushdown(sta[top--]);
    		
    		while (!isroot(x))
    		{
    			int y=fa[x],z=fa[y];
    			if (!isroot(y))
    			{
    				if (ch[z][0]==y^ch[y][0]==z) rot(y);
    				else rot(x);
    			}
    			rot(x);
    		}
    	}
    	void access(int x)
    	{for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,update(x);}
    	void makeroot(int x)
    	{access(x);splay(x);rev[x]^=1;}
    	int find(int x)
    	{access(x);splay(x);while(ch[x][0])x=ch[x][0];return x;}
    	void link(int x,int y)
    	{makeroot(x);fa[x]=y;}
    	void cut(int x,int y)
    	{makeroot(x);access(y);splay(y);if (ch[y][0]==x)fa[x]=0;}
    	int query(int x,int y)
    	{makeroot(x);access(y);splay(y);return mx[y];}
    	void init()
    	{memset(mx,-1,sizeof mx);}
    	void modify(int x)
    	{access(x);splay(x);col[x]^=1;update(x);}
    }lct;
    
    int n,q;
    
    int main()
    {
    	freopen("in.txt","r",stdin);
    	scanf("%d%d",&n,&q);
    	lct.init();
    	for (int i=1;i<n;++i)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		lct.link(x,y);
    	}
    	while (q--)
    	{
    		int op,v;
    		scanf("%d%d",&op,&v);
    		if (op==0) lct.modify(v);
    		else printf("%d
    ",lct.query(1,v));
    	}
    }
    

      

  • 相关阅读:
    组合模式
    迭代器模式
    命令模式
    装饰者模式
    观察者模式
    策略模式
    适配器模式和外观模式
    Servlet
    Java 递归
    Java 反射
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6361710.html
Copyright © 2011-2022 走看看