cogs 1341 永无乡
【题目描述】
永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。
【输入格式】
输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000
对于 100%的数据 n≤100000,m≤n,q≤300000【输出格式】
对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。
【样例输入】
5 1 4 3 2 5 1 1 2 7Q 3 2 Q 2 1 B 2 3 B 1 5 Q 2 1 Q 2 4 Q 2 3【样例输出】
-12512
启发式合并么。。。用并查集维护岛屿之间的连通性,并打上size标记来维护岛屿集合的大小。用log数据结构维护每个岛屿集合的所有重要度排名。合并的时候把小的集合暴力插入到大的集合里。这样的话每次合并后大小至少乘以二。最多乘log次,所以最后复杂度是nlog^2n(大概吧。。。)。
平衡树看起来都很难写啊。。。于是并没有写平衡树。。。01trie还是很好的。。。注意到n不超过10W。。。也就是说树的最大深度就是17咯。。。平衡树的最大深度也是1吧。。。所以跑进了rank10???至于01trie怎么合并。。。看置顶的那篇文章吧(神奇的log合并)。。。STL的list是个坑。。。splice、size操作就是O(n)的。。。所以手写了一个链表。。。(也就是说key值的合并是O(1)的了。。。当然没什么用。。。毕竟还有O(nlogn)的插入操作。。。)不过这么说的话vector似乎就行了???注意垃圾清理啊。。。不然内存要开O(nlog^2n)了(大概)。。。会MLE的(亲测,如果前面的假设没有错的话。。。)。。。
拍照留念?
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <list> 7 8 using namespace std; 9 10 const int N = 100010; 11 12 int n, m, q, x, y, id[N]; 13 char op[10]; 14 15 int GC[N], gcp; 16 17 int keys[N], hd[N], nxt[N], lst[N]; 18 19 int root[N], ch[N * 20][2], sum[N * 20]; 20 21 int New() { 22 static int cnt = 0; 23 if(gcp) { 24 int rt =GC[gcp --]; 25 if(rt[ch][0]) { 26 GC[++ gcp] = rt[ch][0]; 27 } 28 if(rt[ch][1]) { 29 GC[++ gcp] = rt[ch][1]; 30 } 31 rt[ch][0] = rt[ch][1] = 0; 32 rt[sum] = 0; 33 return rt; 34 } else { 35 return ++ cnt; 36 } 37 } 38 39 #define walk for(int i = 16, t ; (t = (val >> i) & 1), ~i ; i --) 40 41 void ins(int rt, int val) { 42 walk { 43 if(rt[ch][t] == 0) rt[ch][t] = New(); 44 (rt = rt[ch][t])[sum] ++; 45 } 46 } 47 48 int kth(int rt, int val) { 49 int ret = 0; 50 walk { 51 if(val > rt[ch][0][sum]) { 52 val -= rt[ch][0][sum]; 53 ret |= 1 << i; 54 rt = rt[ch][1]; 55 } else { 56 rt = rt[ch][0]; 57 } 58 } 59 return ret; 60 } 61 62 int acc[N], size[N]; 63 64 void init(int n) { 65 for(int i = 1 ; i <= n ; i ++) { 66 i[acc] = i; 67 i[size] = 1; 68 } 69 } 70 71 int find(int x) { 72 return x == x[acc] ? x : x[acc] = find(x[acc]); 73 } 74 75 void uni(int x, int y) { 76 x = find(x); 77 y = find(y); 78 if(x != y) { 79 y[size] += x[size]; 80 x[acc] = y; 81 } 82 } 83 84 void merge(int x, int y) { 85 x = find(x); 86 y = find(y); 87 if(x != y) { 88 if(x[size] > y[size]) { 89 swap(x, y); 90 } 91 for(int i = x[hd] ; i ; i = nxt[i]) { 92 ins(y, keys[i]); 93 if(nxt[i] == 0) { 94 y[lst][nxt] = x; 95 y[lst] = x[lst]; 96 } 97 } 98 GC[++ gcp] = x; 99 uni(x, y); 100 } 101 } 102 103 int ask(int rt, int k) { 104 rt = find(rt); 105 if(rt[size] < k) { 106 return -1; 107 } else { 108 int res = kth(rt, k); 109 return res[id]; 110 } 111 } 112 113 int main() { 114 freopen("bzoj_2733.in", "r", stdin); 115 freopen("bzoj_2733.out", "w", stdout); 116 scanf("%d%d", &n, &m); 117 init(n); 118 for(int i = 1 ; i <= n ; i ++) { 119 i[root] = New(); 120 } 121 for(int i = 1 ; i <= n ; i ++) { 122 scanf("%d", &x); 123 x[id] = i; 124 ins(i[root], x); 125 i[keys] = x; 126 i[hd] = i; 127 i[lst] = i; 128 } 129 for(int i = 1 ; i <= m ; i ++) { 130 scanf("%d%d", &x, &y); 131 merge(x, y); 132 } 133 scanf("%d", &q); 134 for(int i = 1 ; i <= q ; i ++) { 135 scanf("%s%d%d", op, &x, &y); 136 if(op[0] == 'B') { 137 merge(x, y); 138 } else { 139 printf("%d\n", ask(x, y)); 140 } 141 } 142 return 0; 143 }
手写链表版
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <vector> 7 8 #define walk for(int i = 16, t ; (t = (val >> i) & 1), ~i ; i --) 9 10 using namespace std; 11 12 const int N = 100010; 13 14 int n, m, q, x, y, id[N]; 15 16 char op[10]; 17 18 int GC[N], gcp; 19 20 vector<int> keys[N]; 21 22 int root[N], ch[N * 20][2], sum[N * 20]; 23 24 int acc[N], size[N]; 25 26 int New() { 27 static int cnt = 0; 28 if(gcp) { 29 int rt =GC[gcp --]; 30 if(rt[ch][0]) { 31 GC[++ gcp] = rt[ch][0]; 32 } 33 if(rt[ch][1]) { 34 GC[++ gcp] = rt[ch][1]; 35 } 36 rt[ch][0] = rt[ch][1] = 0; 37 rt[sum] = 0; 38 return rt; 39 } else { 40 return ++ cnt; 41 } 42 } 43 44 void ins(int rt, int val) { 45 walk { 46 if(rt[ch][t] == 0) rt[ch][t] = New(); 47 (rt = rt[ch][t])[sum] ++; 48 } 49 } 50 51 int kth(int rt, int val) { 52 int ret = 0; 53 walk { 54 if(val > rt[ch][0][sum]) { 55 val -= rt[ch][0][sum]; 56 ret |= 1 << i; 57 rt = rt[ch][1]; 58 } else { 59 rt = rt[ch][0]; 60 } 61 } 62 return ret; 63 } 64 65 void init(int n) { 66 for(int i = 1 ; i <= n ; i ++) { 67 i[acc] = i; 68 i[size] = 1; 69 } 70 } 71 72 int find(int x) { 73 return x == x[acc] ? x : x[acc] = find(x[acc]); 74 } 75 76 void uni(int x, int y) { 77 x = find(x); 78 y = find(y); 79 if(x != y) { 80 y[size] += x[size]; 81 x[acc] = y; 82 } 83 } 84 85 void merge(int x, int y) { 86 x = find(x); 87 y = find(y); 88 if(x != y) { 89 if(x[size] > y[size]) 90 swap(x, y); 91 for(int i = 0 ; i < x[keys].size() ; i ++) { 92 ins(y, x[keys][i]); 93 y[keys].push_back(x[keys][i]); 94 } 95 GC[++ gcp] = x; 96 uni(x, y); 97 } 98 } 99 100 int ask(int rt, int k) { 101 rt = find(rt); 102 if(rt[size] < k) { 103 return -1; 104 } else { 105 int res = kth(rt, k); 106 return res[id]; 107 } 108 } 109 110 int main() { 111 freopen("bzoj_2733.in", "r", stdin); 112 freopen("bzoj_2733.out", "w", stdout); 113 114 scanf("%d%d", &n, &m); 115 init(n); 116 for(int i = 1 ; i <= n ; i ++) { 117 i[root] = New(); 118 } 119 120 for(int i = 1 ; i <= n ; i ++) { 121 scanf("%d", &x); 122 x[id] = i; 123 ins(i[root], x); 124 i[keys].push_back(x); 125 } 126 127 for(int i = 1 ; i <= m ; i ++) { 128 scanf("%d%d", &x, &y); 129 merge(x, y); 130 } 131 132 scanf("%d", &q); 133 134 for(int i = 1 ; i <= q ; i ++) { 135 scanf("%s%d%d", op, &x, &y); 136 if(op[0] == 'B') { 137 merge(x, y); 138 } else { 139 printf("%d\n", ask(x, y)); 140 } 141 } 142 return 0; 143 }
vector版
转载于:https://www.cnblogs.com/KingSann/articles/7351284.html
cogs 1341 永无乡相关推荐
- [bzoj2733]永无乡 [bzoj1503]郁闷的出纳员
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1321 Solved: 693 [Submit][Stat ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- 数据结构之线段树合并——永无乡,Lomsat gelral,Tree Rotations,Tree Rotations Escape Through Leaf
文章目录 [HNOI2012]永无乡 Lomsat gelral 「POI2011 R2 Day2」旋转树木 Tree Rotations Escape Through Leaf 线段树合并与 fhq ...
- 数据结构之fhq-treap——Chef and Sets,[HNOI2012]永无乡,Play with Chain,[NOI2005]维修数列(结构体版代码)
因为非常板,所以主要是代码 Tyvj 1728 普通平衡树 Chef and Sets [HNOI2012]永无乡 Play with Chain [NOI2005]维修数列 题目很水,所以可能会出现 ...
- P3224 [HNOI2012]永无乡(并查集+权值线段树合并/平衡树)
[HNOI2012]永无乡 Code1 权值线段树天然支持merge,线段树上二分求第k小 #include<bits/stdc++.h>using namespace std; usin ...
- bzoj2733永无乡
永无乡 HYSBZ - 2733 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接, ...
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 3850 Solved: 2061 [Submit][Sta ...
- [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
最新文章
- HTTPS网络加密双向验证-使用AFNetworking封装
- 文件查找命令find的使用
- Hadoop源码分析-Context
- centos8中一键安装Nginx
- Hadoop动态扩容,增加节点
- 15行代码AC——1019 数字黑洞 (20分) 甲级1069. The Black Hole of Numbers (20)(解题报告)
- 一个很不错的LINUX基本操作归纳
- BAT执行DOS命令查找本地浏览器
- NVelocity标签设置缓存的解决方案
- C++基础部分_C++文件操作_二进制文件的写操作---C++语言工作笔记078
- 一次weblogic 在aix hacmp上调试过程
- linux进程号转换成16进制,linux-shell 脚本转换 十六进制 十进制 八进制 二进制
- golang ide 下载
- java 关键字 assert的学习
- GitHub 总星 4w+!删库?女装?表情包?这些沙雕中文项目真是我每天快乐的源泉!
- cgb2111-day02
- Web安全工具大集合
- 集成测试最全详解,看完必须懂了
- 从博客搭建和装修学到的东西
- (九五至尊)九大管理体系,五大过程组:软考高级信息系统项目管理师
热门文章
- 计算机竞赛的数学知识,可以参加的数学类和计算机类竞赛有哪些?
- 文字图片OCR识别神器 没有不能复制的文字
- Sox语音转换的相关知识
- 1月10日前未完成《创业创新执行力》考试的补救措施
- T/CAGIS 1—2019《空间三维模型数据格式》
- Qt安装及配置资源链接
- 请看今日之域中,竟是谁家之天下!-----------2021 年 7 月 TIOBE 指数,“三国争霸”最终谁能登顶?他们的命运掌握在各位大佬的手中
- access vba表字段_ACCESS VBA编程(使用技巧大全)[].doc
- 我的编程之路:「懒惰」是程序员最大的美德
- Predict Binding Sites of Transcription Factor 富集分析