[bzoj3123]森林
首先对于询问操作可以使用可持久化线段树来维护,对于连边操作对于两颗树中选取较小的树暴力练到另一个点上,点数可以用并查集然后只修改根的点数即可。
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define mid (l+r>>1)
4 #define N 100001
5 struct ji{
6 int nex,to;
7 }edge[N<<1];
8 int E,V,n,m,t,x,y,z,ans,a[N],ff[N],sum[N],f[21][N],head[N],sz[20*N],b[N],son[2][20*N],s[N],r[N],vis[N];
9 char s1[11];
10 void add(int x,int y){
11 edge[E].nex=head[x];
12 edge[E].to=y;
13 head[x]=E++;
14 }
15 int find(int k){
16 if (k==ff[k])return k;
17 return ff[k]=find(ff[k]);
18 }
19 int ne(int &k){
20 if (!k)k=++V;
21 return k;
22 }
23 int lca(int x,int y){
24 if (s[x]<s[y])swap(x,y);
25 for(int i=20;i>=0;i--)
26 if (s[f[i][x]]>=s[y])x=f[i][x];
27 if (x==y)return x;
28 for(int i=20;i>=0;i--)
29 if (f[i][x]!=f[i][y]){
30 x=f[i][x];
31 y=f[i][y];
32 }
33 return f[0][x];
34 }
35 void merge(int x,int y){
36 ff[find(x)]=find(y);
37 sum[find(y)]+=sum[find(x)];
38 }
39 void update(int k1,int k2,int l,int r,int x){
40 sz[k1]=sz[k2]+1;
41 if (l==r)return;
42 int p=(x>mid);
43 son[p^1][k1]=son[p^1][k2];
44 update(ne(son[p][k1]),son[p][k2],l+(mid-l+1)*p,mid+(r-mid)*p,x);
45 }
46 int query(int l,int r,int x,int a,int b,int c,int d){
47 if (l==r)return l;
48 int t=sz[son[0][a]]+sz[son[0][b]]-sz[son[0][c]]-sz[son[0][d]],p=(x>t);
49 return query(l+(mid-l+1)*p,mid+(r-mid)*p,x-p*t,son[p][a],son[p][b],son[p][c],son[p][d]);
50 }
51 void dfs(int k,int fa){
52 vis[k]=1;
53 s[k]=s[f[0][k]=fa]+1;
54 for(int i=1;i<=20;i++)f[i][k]=f[i-1][f[i-1][k]];
55 update(ne(r[k]),r[fa],1,m,a[k]);
56 for(int i=head[k];i!=-1;i=edge[i].nex)
57 if (edge[i].to!=fa)dfs(edge[i].to,k);
58 }
59 int main(){
60 scanf("%*d%d%d%d",&n,&m,&t);
61 memset(head,-1,sizeof(head));
62 for(int i=1;i<=n;i++){
63 scanf("%d",&a[i]);
64 ff[i]=i;
65 sum[i]=1;
66 }
67 for(int i=1;i<=m;i++){
68 scanf("%d%d",&x,&y);
69 add(x,y);
70 add(y,x);
71 merge(x,y);
72 }
73 memcpy(b,a,sizeof(b));
74 sort(b+1,b+n+1);
75 m=unique(b+1,b+n+1)-b-1;
76 for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
77 for(int i=1;i<=n;i++)
78 if (!vis[i])dfs(i,0);
79 while (t--){
80 scanf("%s%d%d",s1,&x,&y);
81 x^=ans;
82 y^=ans;
83 if (s1[0]=='Q'){
84 scanf("%d",&z);
85 printf("%d\n",ans=b[query(1,m,z^ans,r[x],r[y],r[lca(x,y)],r[f[0][lca(x,y)]])]);
86 }
87 if (s1[0]=='L'){
88 if (sum[find(x)]>sum[find(y)])swap(x,y);
89 add(x,y);
90 add(y,x);
91 merge(x,y);
92 dfs(x,y);
93 }
94 }
95 }
[bzoj3123]森林的更多相关文章
- 【BZOJ3123】森林(主席树,启发式合并)
题意:一个带点权的森林,要求维护以下操作: 1.询问路径上的点权K大值 2.两点之间连边 n,m<=80000 思路:如果树的结构不发生变化只需要维护DFS序 现在因为树的结构发生变化,要将两棵 ...
- 【BZOJ3123】[Sdoi2013]森林 主席树+倍增LCA+启发式合并
[BZOJ3123][Sdoi2013]森林 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整 ...
- [bzoj3123][Sdoi2013]森林_主席树_启发式合并
森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- [BZOJ3123][Sdoi2013]森林 主席树+启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...
- 【BZOJ-3123】森林 主席树 + 启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2738 Solved: 806[Submit][Status] ...
- BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4813 Solved: 1420[Submit][Status ...
- 【BZOJ3123】[SDOI2013] 森林(启发式合并主席树)
点此看题面 大致题意: 给你一片森林,有两种操作:询问两点之间的第\(k\)小点权和在两棵树之间连一条边. 前置技能:树上主席树 做这道题目,我们首先要会树上主席树. 关于树上主席树,这有一道很好的例 ...
- 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...
随机推荐
- 怒肝 Linux 学习路线,这回不难
Linux 学习路线 by 鱼皮. 原创不易,请勿抄袭,违者必究! 大家好,我是鱼皮,又花 1 周肝出了 Linux 学习资料全家桶,包括学习路线.命令手册.视频.书籍.文档.实战教程.社区.工具.大 ...
- qsort()函数的使用
函数声明 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) 参数 ...
- Mac录屏同时录制系统声音和画外音(Soundflower无法安装解决方案)
个人博客地址:xzajyjs.cn 前言 以前一直有录屏的需求,但苦于自带的QuickTime 无法录制内屏声音,一直使用的是第三方的app.近期开腾讯会议需要录屏,但主持人本身没有开启录屏权限,只好 ...
- C语言中while 语句
while的执行顺序 while 循环的执行顺序非常简单,它的格式是: while (表达式) { 语句: } 概念:当表达式为真,则执行下面的语句:语句执行完之后再判断表达式是否为真,如果为真,再次 ...
- Java内存分析--栈--堆
Java内存分析--栈--堆 JVM的内存分析: 1.栈内存 1.连续的存储空间,遵循后进先出的原则. 2.每个线程包含一个栈区,栈区只保存基础数据类型的对象和自定义对象的引用. 3.每个栈中的数据都 ...
- Succeed_School
# Author kevin_hou class School(object): def __init__(self,name,addr): self.name = name self.addr = ...
- [对对子队]Alpha阶段项目展示博客
Alpha阶段项目展示博客 1 团队成员的简介和个人博客地址 成员 头像 岗位 博客 个人介绍 黄贤昊 PM 17373253 喜欢玩游戏和做游戏,项目经验基本都和游戏相关,擅长摸鱼,偶尔敬业. 刘子 ...
- [no_code][Alpha]测试报告
项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 测试报告 我们在这个课程的目标是 设计出一个OCR表单处理软件 这个作业在哪个具体方面 ...
- 2021.10.10考试总结[NOIP模拟73]
T1 小L的疑惑 对于\(P_i\),如果所有比\(P_i\)小的数加起来也达不到\(P_i-1\),那么值域肯定不连续.否则设原来值域最大值为\(mx\),则\(P_i\)会让值域最大值增致\(mx ...
- C语言中都有哪些常见的数据结构你都知道几个??
上次在面试时被面试官问到学了哪些数据结构,那时简单答了栈.队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了一下几种常见的数据结构,原来我们学过的数据结构有这么多~ 首先,先来回顾下C语言中常见 ...