zoukankan      html  css  js  c++  java
  • UOJ207 共价大爷游长沙

    考虑到路径是有向的,不是很好维护。
    如果路径无向的话,可以直接转化为链加和查询操作。
    既然有向的话,不妨考虑一波hash。
    对于一组询问x,y,可以把树划分为两颗子树。
    合法显然需要满足
    x子树的起点的hash=y子树的终点的hash
    x子树的终点的hash=y子树的起点的hash
    直接用LCT维护一个异或hash即可。

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    #define N 330000
    #define L 300000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    using namespace std;
    inline int read()
    {
    	char ch=0;
    	int x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*flag;
    }
    #define lson son[x][0]
    #define rson son[x][1] 
    struct lnk{int x,y,z;}p[N];
    int va[N],vb[N],sa[N],sb[N],sa_[N],sb_[N],f[N],st[N],flag[N],son[N][2];
    bool get(int x){return son[f[x]][1]==x;}
    bool isroot(int x){return (son[f[x]][0]!=x)&&(son[f[x]][1]!=x);}
    void pushup(int x)
    {
    	sa[x]=sa[lson]^sa[rson]^sa_[x]^va[x];
    	sb[x]=sb[lson]^sb[rson]^sb_[x]^vb[x];
    }
    void update(int x){flag[x]^=1;swap(lson,rson);}
    void pushdown(int x){if(!flag[x])return;if(lson)update(lson);if(rson)update(rson);flag[x]=0;}
    void rotate(int x)
    {
    	int y=f[x],z=f[y],tx=get(x),ty=get(y),p=son[x][!tx];
    	if(!isroot(y))son[z][ty]=x;son[x][!tx]=y;son[y][tx]=p;
    	if(p)f[p]=y;f[y]=x;f[x]=z;pushup(y);pushup(x);
    }
    void splay(int x)
    {
    	int cnt=0,tmp=x;
    	st[++cnt]=x;
    	while(!isroot(x))st[++cnt]=f[x],x=f[x];
    	for(int i=cnt;i>=1;i--)pushdown(st[i]);
    	x=tmp;
    	while(!isroot(x))
    	{
    		int y=f[x];
    		if(!isroot(y))rotate(get(x)==get(y)?y:x);
    		rotate(x);
    	}
    	pushup(x);
    }
    void access(int x)
    {
    	for(int y=0;x;y=x,x=f[x])
    	{
    		splay(x);
    		sa_[x]^=sa[rson];
    		sb_[x]^=sb[rson];
    		rson=y;
    		sa_[x]^=sa[rson];
    		sb_[x]^=sb[rson];
    		pushup(x);
    	}
    }
    void makeroot(int x){access(x);splay(x);update(x);}
    void link(int x,int y)
    {
    	makeroot(x);access(y);splay(y);
    	f[x]=y;sa_[y]^=sa[x];sb_[y]^=sb[x];
    	pushup(y);
    }
    void cut(int x,int y)
    {
    	makeroot(x);access(y);splay(y);
    	f[x]=son[y][0]=0;pushup(y);
    }
    void add1(int x,int k){makeroot(x);va[x]^=k;pushup(x);}
    void add2(int x,int k){makeroot(x);vb[x]^=k;pushup(x);}
    int rng(){int x=0;for(int i=0;i<=30;i++)x^=(rand()%2)<<i;return x;}
    int main()
    {
    	srand(time(0));read();
    	int n=read(),m=read(),cnt=0,s=0;
    	for(int i=1;i<n;i++){int x=read(),y=read();link(x,y);}
    	for(int i=1;i<=m;i++)
    	{
    		int flag=read();
    		if(flag==1)
    		{
    			int x,y;
    			x=read();y=read();cut(x,y);
    			x=read();y=read();link(x,y);
    		}
    		if(flag==2)
    		{
    			cnt++;
    			p[cnt].x=read();p[cnt].y=read();p[cnt].z=rng();
    			add1(p[cnt].x,p[cnt].z);add2(p[cnt].y,p[cnt].z);s^=p[cnt].z;
    		}
    		if(flag==3)
    		{
    			int k=read();
    			add1(p[k].x,p[k].z);add2(p[k].y,p[k].z);s^=p[k].z;
    		}
    		if(flag==4)
    		{
    			int x=read(),y=read();
    			makeroot(x);access(y);
    			int a=sa_[y]^va[y],b=sb_[y]^vb[y]; 
    			if((a^b)==s)printf("YES
    ");
    			else printf("NO
    ");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    CSS 使DIV居中
    jsonlib 使用 转换JSON
    jquery autocomplete 自动完成 使用
    Sql server 实用技巧总结
    MvcHtml.DropDownList()用法
    日期时间正则表达式
    ASP.NET使用log4Net日志组件教程(每天产生一个日志及日志按大小切割)
    MvcHtml.ActionLink()用法
    给学弟的bitset使用整理
    2021 CCPC 广州站
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10354399.html
Copyright © 2011-2022 走看看