题目大意

一颗会动的树。
有一个点对集合会变。
每次询问一条树边,问集合内所有点对之间的路径是否都经过该边。

维护虚边信息的LCT

终于无聊来补了这题
每个点对随机一个10^9内的权值
然后给两端点的点权分别异或给权值。
询问一条边是否被全部经过,就是询问每个点对是否都被这条边分开。
那么比如这条边是(u,v),断开后u的子树异或和应该要等于当前所有路径权值异或和。
就可以判了,出错率当然是很低啦。

#include<cstdio>
#include<algorithm>
#include<ctime>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=100000+10,maxm=300000+10,md=1000000000;
int ask[maxm][5],size[maxm*4],c[maxm],b[maxm];
int key[maxn],num[maxn],siz[maxn],father[maxn],tree[maxn][2],pp[maxn],sum[maxn],sta[maxn];
bool bz[maxn];
int h[maxn],go[maxn*2],next[maxn*2];
int i,j,k,u,v,l,t,n,m,tot,top,wdc,ans,id;
int random(int x){ll t=rand()%10000;t=t*10000+rand()%10000;t=t*10000+rand()%10000;return t%x;
}
int read(){int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
void add(int x,int y){go[++tot]=y;next[tot]=h[x];h[x]=tot;
}
void dfs(int x,int y){pp[x]=y;int t=h[x];while (t){if (go[t]!=y) dfs(go[t],x);t=next[t];}
}
int pd(int x){return tree[father[x]][1]==x;
}
void update(int x){siz[x]=siz[tree[x][0]]^siz[tree[x][1]]^key[x];num[x]=num[tree[x][0]]^num[tree[x][1]]^sum[x];
}
void rotate(int x){int y=father[x],z=pd(x);father[x]=father[y];if (father[y]) tree[father[y]][pd(y)]=x;tree[y][z]=tree[x][1-z];if (tree[x][1-z]) father[tree[x][1-z]]=y;tree[x][1-z]=y;father[y]=x;update(y);update(x);if (pp[y]) pp[x]=pp[y],pp[y]=0;
}
void clear(int x){if (bz[x]){if (tree[x][0]) bz[tree[x][0]]^=1;if (tree[x][1]) bz[tree[x][1]]^=1;swap(tree[x][0],tree[x][1]);bz[x]=0;}
}
void remove(int x,int y){top=0;while (x!=y){sta[++top]=x;x=father[x];}while (top){clear(sta[top]);top--;}
}
void splay(int x,int y){remove(x,y);while (father[x]!=y){if (father[father[x]]!=y) if (pd(x)==pd(father[x])) rotate(father[x]);else rotate(x);rotate(x);}
}
int find_left(int x){if (!x) return 0;clear(x);if (!tree[x][0]) return x;else return find_left(tree[x][0]);
}
int getnum(int x){splay(x,0);return sum[x]^num[tree[x][1]]^siz[tree[x][1]]^key[x];
}
void real_empty(int x,int y){int t=getnum(x);splay(y,0);splay(x,y);tree[y][1]=0;father[x]=0;pp[x]=y;sum[y]^=t;update(y);
}
void empty_real(int x,int y){int t=getnum(x);splay(y,0);splay(x,0);tree[y][1]=x;father[x]=y;pp[x]=0;sum[y]^=t;update(y);
}
void access(int x){int y,z;splay(x,0);z=find_left(tree[x][1]);if (z){splay(z,x);real_empty(z,x);}while (pp[x]){y=pp[x];splay(y,0);z=find_left(tree[y][1]);if (z){splay(z,y);real_empty(z,y);}splay(x,0);z=find_left(x);splay(z,0);empty_real(z,y);splay(x,0);}
}
void makeroot(int x){access(x);splay(x,0);bz[x]^=1;
}
void cut(int x,int y){makeroot(x);access(x);int t=getnum(y);splay(x,0);sum[x]^=t;update(x);splay(y,0);pp[y]=0;
}
void link(int x,int y){makeroot(x);makeroot(y);int t=getnum(y);splay(x,0);sum[x]^=t;update(x);splay(y,0);pp[y]=x;
}
void insert(int p,int l,int r,int a,int b){if (l==r){size[p]+=b;return;}int mid=(l+r)/2;if (a<=mid) insert(p*2,l,mid,a,b);else insert(p*2+1,mid+1,r,a,b);size[p]=size[p*2]+size[p*2+1];
}
int kth(int p,int l,int r,int k){if (l==r) return l;int mid=(l+r)/2;if (k<=size[p*2]) return kth(p*2,l,mid,k);else return kth(p*2+1,mid+1,r,k-size[p*2]);
}
int main(){//freopen("data.in","r",stdin);freopen("data.out","w",stdout);srand(time(0));id=read();n=read();m=read();fo(i,1,n-1){j=read();k=read();add(j,k);add(k,j);}dfs(1,0);tot=0;fo(i,1,m){ask[i][0]=read();ask[i][1]=read();if (ask[i][0]!=3) ask[i][2]=read();if (ask[i][0]==1) ask[i][3]=read(),ask[i][4]=read();if (ask[i][0]==2) ask[i][3]=++tot,c[tot]=i;}fo(i,1,m){if (ask[i][0]==1){j=ask[i][1];k=ask[i][2];u=ask[i][3];v=ask[i][4];cut(j,k);link(u,v);}else if (ask[i][0]==2){insert(1,1,tot,ask[i][3],1);j=ask[i][1];k=ask[i][2];b[ask[i][3]]=random(md)+1;access(j);splay(j,0);key[j]^=b[ask[i][3]];update(j);access(k);splay(k,0);key[k]^=b[ask[i][3]];update(k);wdc^=b[ask[i][3]];}else if (ask[i][0]==3){//t=kth(1,1,tot,ask[i][1]);t=ask[i][1];insert(1,1,tot,t,-1);j=ask[c[t]][1];k=ask[c[t]][2];access(j);splay(j,0);key[j]^=b[ask[c[t]][3]];update(j);access(k);splay(k,0);key[k]^=b[ask[c[t]][3]];update(k);wdc^=b[ask[c[t]][3]];}else{j=ask[i][1];k=ask[i][2];cut(j,k);makeroot(j);ans=getnum(j);if (ans==wdc) printf("YES\n");else printf("NO\n");link(j,k);}}
}

[UOJ#207]共价大爷游长沙相关推荐

  1. 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息

    题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...

  2. 【uoj207】 共价大爷游长沙

    http://uoj.ac/problem/207 (题目链接) 题意 给出一棵无根树,4种操作:在路径集合中加入一条路径,在路径集合中删除一条路径,删一条边加一条边,查询一条边是否被集合中所有路径经 ...

  3. 【UOJ207】共价大爷游长沙【LCT】【异或】【随机化】

    传送门 题意:维护一棵无权树和一个路径集合SSS,支持以下操作: 断边连边 在SSS加入中加入一条路径 删除SSS中的一条路径 询问是否SSS中的所有路径都经过了边(x,y)(x,y)(x,y) n≤ ...

  4. UOJ207 共价大爷游长沙

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

  5. 一句话题解(20170801~20170125)

    8.1 bzoj 4720 noip2016 换教室 floyd预处理+期望(薛定谔的猫) bzoj 4318 OSU! 三次函数期望值 从一次.二次推得 8.2 bzoj 1076 状压+期望DP ...

  6. ZJOI2019Round#1

    考的这么差二试基本不用去了 不想说什么了.就把这几天听课乱记的东西丢上来吧 这里是二试乱听课笔记ZJOI2019Round#2 ZJOI Round#1 Day1 M.<具体数学>选讲 罗 ...

  7. 跑出数字化升级“加速度”,腾讯云启产业基地“长沙模式”的探索

    文 | 曾响铃 来源 | 科技向令说(xiangling0815) 当互联网与产业加速融合,数字经济成为发展新引擎. 在长沙,2019年,深耕岩土工程自动化监测领域的湖南湘银河传感科技有限公司,借助湘 ...

  8. 画论38 董其昌《画禅室随笔》

    [中国历代画论目录] 目录 卷一 ◎论用笔 ◎评法书 ◎跋自书 ◎评古帖 卷二 ◎画诀 ◎画源 ◎题自画 ◎评旧画 卷三 ◎记事 ◎记游 ◎评诗 ◎评文 卷四 ◎杂言上 ◎杂言下 ◎楚中随笔 ◎禅悦 ...

  9. 书论66 董其昌《画禅室随笔》

    目录 卷一 论用笔 评法书 评古帖 卷二 画诀 画源 题自画 评旧画 论画 卷三 记事 记游 评诗 评文 卷四 杂言上 杂言下 楚中随笔 禅悦 卷一 论用笔 米海岳书,无垂不缩,无往不收.此八字真言, ...

最新文章

  1. Java分布式 RPC 框架性能大比拼,Dubbo最差?
  2. 9 岁自学编程、24 岁身价涨至数百万美元,与微软一较高低的大佬多厉害?
  3. SQL Server之其他函数——空值处理
  4. Ajax -get 请求
  5. 坐标偏差大_控制点的坐标复核(二)
  6. .ini文件中的PHP 5.6 error_reporting设置不起作用
  7. 记一些暂未找到解决方案的问题 -- 持续更新
  8. git 回退上一个版本_Git小白使用教程:详细、显现、真正手把手教!
  9. go 二进制程序守护_图解 Go 程序是怎样跑起来的
  10. 盒子模型阴影设置,爱奇艺阴影配置
  11. [剑指offer][JAVA]面试题第[30]题[包含min函数的栈][双栈辅助栈][单栈]
  12. 【CodeForces - 298C】Parity Game (思维,有坑)
  13. DataGrid的动态绑定问题(二)
  14. 2.shell 程序设计(1)
  15. 揭示Win32 API拦截细节/API hooking revealed (2)
  16. visio2010安装
  17. mysql读mdf_mdf文件导入mysql,mysql怎么导入mdf文件 | 帮助信息-动天数据
  18. matlab版本低能用吗,MATLAB高版本打开低版本
  19. 如何精细化APP运营
  20. 大数据是什么意思?就业前景如何?

热门文章

  1. python简单命令_python常用命令有哪些
  2. 移动安全之Android安全检测工具大全
  3. 基于电流型磁链观测器的异步电机矢量控制学习
  4. 同一台 win10 服务器跑多个 wiki(包括 DokuWiki、django-wiki)
  5. TIOBE 2012年9月编程语言排行榜:C语言老当益壮
  6. 华三服务器管理口地址_h3c 的交换机怎样设置管理地址?
  7. 各大牛逼网站推荐系统
  8. 嵌入式的可就业方向有哪些?
  9. 生产者消费者模型详解以及实现
  10. Vue 获取 DOM--实例,页面一打开被focus