[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 ...
随机推荐
- oracle 不能用上下键调用sql语句
在Linux的sqlplus中运行SQL语句之后,想用上下键把历史命令找出来,发现不支持. 安装rlwrap 重启sqlplus 3,使用rlwrap,rlwrap sqlplus / as sysd ...
- 基于ZooKeeper,Spring设计实现的参数系统
一.简介 基于ZooKeeper服务端.ZooKeeper Java客户端以及Spring框架设计的用于系统内部进行参数维护的系统. 二.设计背景 在我们日常开发的系统内部,开发过程中最常见的一项工作 ...
- 解决VSCODE"因为在此系统上禁止运行脚本"报错
在VSCODE中使用yarn,结果报错: 找了下原因,是因为PowerShell执行策略的问题. 解决方法: 以管理员身份运行vscode; 执行:get-ExecutionPolicy,显示R ...
- 洛谷5024 保卫王国 (动态dp)
qwq非正解. 但是能跑过. 1e5 log方还是很稳的啊 首先,考虑最普通的\(dp\) 令\(dp1[x][0]表示不选这个点,dp1[x][1]表示选这个点的最大最小花费\) 那么 \(dp1[ ...
- 破解安装pyhotn
1.网址 https://www.jetbrains.com/pycharm/download/#section=windows,打开页面,点击下载专业版 2.这是下载好的文件,双击运行即可. //详 ...
- python中对列表的排序
1.sort()对列表永久性的排序,首字母按照字母表的顺序排列 book=['python','java','c++','web'] book.sort() print(book) 结果如下: 2.向 ...
- 剑指offer:JZ9 用两个栈实现队列
JZ9 用两个栈实现队列 描述 用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能. 队列中的元素为int类型.保证操作合法,即保 ...
- Alpha-功能规格说明书
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-功能规格说明书 一.引言 1. 项目简介 项目团队:删库跑路对不队 项目名称:题士 项目内容 ...
- [敏捷软工团队博客]The Agiles 团队介绍&团队采访
项目 内容 课程:北航-2020-春-敏捷软工 博客园班级博客 作业要求 团队作业-团队介绍和采访 团队名称来源 The Agile is The Agile. 敏捷就是敏捷.我们只是敏捷的践行者罢了 ...
- UVA-1016 Silly Sort
UVA-1016 题目大意:给定一个长度为n的序列,每次操作可以交换任意两个数的位置,代价为两个数的和,求最小代价,将序列排成有序的. 首先,显然需要交换的数一定会形成环: 那么对于每一个环,我们有两 ...