首先对于询问操作可以使用可持久化线段树来维护,对于连边操作对于两颗树中选取较小的树暴力练到另一个点上,点数可以用并查集然后只修改根的点数即可。

 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]森林的更多相关文章

  1. 【BZOJ3123】森林(主席树,启发式合并)

    题意:一个带点权的森林,要求维护以下操作: 1.询问路径上的点权K大值 2.两点之间连边 n,m<=80000 思路:如果树的结构不发生变化只需要维护DFS序 现在因为树的结构发生变化,要将两棵 ...

  2. 【BZOJ3123】[Sdoi2013]森林 主席树+倍增LCA+启发式合并

    [BZOJ3123][Sdoi2013]森林 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整 ...

  3. [bzoj3123][Sdoi2013]森林_主席树_启发式合并

    森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...

  4. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  5. [BZOJ3123][Sdoi2013]森林 主席树+启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...

  6. 【BZOJ-3123】森林 主席树 + 启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2738  Solved: 806[Submit][Status] ...

  7. BZOJ3123: [Sdoi2013]森林(启发式合并&主席树)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4813  Solved: 1420[Submit][Status ...

  8. 【BZOJ3123】[SDOI2013] 森林(启发式合并主席树)

    点此看题面 大致题意: 给你一片森林,有两种操作:询问两点之间的第\(k\)小点权和在两棵树之间连一条边. 前置技能:树上主席树 做这道题目,我们首先要会树上主席树. 关于树上主席树,这有一道很好的例 ...

  9. 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林

    小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...

随机推荐

  1. 编译原理: FIRST(x) FOLLOW(x) SELECT(x)的计算

    目录 First计算 Follow计算 Select计算 已知文法G[S]: S→MH|a H→LSo|ε K→dML|ε L→eHf M→K|bLM 判断G是否是LL(1)文法. First计算 F ...

  2. docker采用registry部署简易仓库

    解释:registry部署简易仓库,实现免密上传拉取镜像(解决不在一个容器里,也能够实现镜像拉取成功) 1.安装启动registry服务 docker pull registry docker run ...

  3. BIBD&SBIBD的矩阵题

    证明不存在 \(01\) 方阵 \(A\) 使得: \(A^TA=\begin{pmatrix}7&2&\dots &2\\2&7&\dots&2\\ ...

  4. CF123E Maze(期望dp,树形dp,式子)

    题目大意: 给你一棵树,边权都是1,每一个点有一个是起点的概率和一个是终点的概率,你将以起点为根,开始在树上随机dfs,每到一个点,就会将他的所有儿子随机打乱成序列,然后按照那个随机顺序走完,直到走到 ...

  5. scratch塔罗牌的制作

    首先,这个程序的流程是洗牌->占卜,很简单的一个程序.那个程序的组成是什么呢? 该程序由22张大卡.开始洗牌按钮.占卜按钮和说出占卜结果的角色组成. 先来说说开始洗牌按钮吧. 开始的时候移动到相 ...

  6. Beta Scrum Meeting汇总

    第0次Alpha Scrum Meeting 第1次Alpha Scrum Meeting 第2次Alpha Scrum Meeting 第3次Alpha Scrum Meeting 第4次Alpha ...

  7. seata代码控制回滚和临时挂起分布式事物

    seata代码控制回滚和临时挂起分布式事物 一.说明 二.功能实现 1.手动回滚分布式事物 2.临时挂起分布式事物 三.完整代码 四 参考链接 一.说明 此处只是简单的记录一下,使用了 Seata后, ...

  8. 联赛膜你测试20 T1 Simple 题解 && NOIP2017 小凯的疑惑 题解(赛瓦维斯特定理)

    前言: 数学题,对于我这种菜B还是需要多磨啊 Simple 首先它问不是好数的数量,可以转化为用总数量减去是好数的数量. 求"好数"的数量: 由裴蜀定理得,如果某个数\(i\)不能 ...

  9. C语言基础知识总结大全

    1.入门程序 #include <stdio.h> int main() { printf("Hello World!"); return 0; } 2.数据类型 数据 ...

  10. 从零开始 DIY 智能家居 - 基于 ESP32 的智能紫外线传感器模块

    目录 前言 硬件选择 二.使用步骤 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与上报流程 总结 前言 做了这么多传感器都是自己玩,这次家里人看不下去了,非得 ...