【ZOJ2334】Monkey King
来源:互联网 发布:cad可以画网络拓扑图吗 编辑:程序博客网 时间:2024/05/18 01:03
题目大意
有
简要分析
我们需要一种数据结构维护元素,支持快速合并,查找最大值。普通的堆并不能快速合并,所以大神们搞出了可并堆这种东西。
左偏树是一种比较好写的可并堆,详细请看BYVOID大神(黑科技:pbds库里有可并堆模板哦!)
AC code :
#include <set>#include <map>#include <ctime>#include <cmath>#include <queue>#include <cstdio>#include <cctype>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define MP make_pair#define PB push_backtypedef long long LL;typedef pair<int, int> pii;inline int read(){ int x = 0; int v = 1, c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if(c == '-') v = -1; for(;c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0'; return x * v;}template<typename T>inline void write(T x, int ch = 10){ int s[20], t = 0; if(x < 0) { x = -x; putchar('-'); } do s[t++] = x % 10; while(x /= 10); while(t--) putchar('0' + s[t]); putchar(ch);}const int maxn = 100005;int n, m, v[maxn];int lc[maxn], rc[maxn], d[maxn], fa[maxn];void input(){ for(int i = 1; i <= n; ++i) v[i] = read(); m = read();}inline void clear(const int &x){ d[x] = lc[x] = rc[x] = 0;}inline void reset(const int &x){ fa[x] = x;}void build(){ for(int i = 1; i <= n; ++i) { reset(i); clear(i); }}int getfa(const int &x){ return fa[x] == x ? x : fa[x] = getfa(fa[x]);}int merge(int a, int b){ if(a == 0) return b; if(b == 0) return a; if(v[a] < v[b]) swap(a, b); rc[a] = merge(rc[a], b); if(rc[a]) fa[rc[a]] = a; if(d[lc[a]] < d[rc[a]]) swap(lc[a], rc[a]); d[a] = rc[a] ? d[rc[a]] + 1 : 0; return a;}int pop(int x){ int l = lc[x], r = rc[x]; reset(l); reset(r); reset(x); clear(x); return merge(l, r);}int modify(int x){ v[x] >>= 1; return merge(x, pop(x));}void solve(){ register int x, y, z; for(int i = 1; i <= m; ++i) { x = getfa(read()); y = getfa(read()); if(x == y) puts("-1"); else { x = modify(x); y = modify(y); z = merge(x, y); write(v[z]); } }}int main(){#ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);#endif while(~scanf("%d", &n)) { input(); build(); solve(); }#ifndef ONLINE_JUDGE fprintf(stderr, "Run Time: %dms\n", clock()); fclose(stdin), fclose(stdout);#endif return 0;}
题外话(黑科技)
使用pbds中的可并堆
一点介绍
原文在这里
包含:ext/pb_ds/priority_queue.hpp
声明:__gnu_pbds::priority_queue
模板参数:
template < typename Value_Type , typename Cmp_Fn = std :: less < Value_Type >, typename Tag = pairing_heap_tag , typename Allocator = std :: allocator <char > >class priority_queue
Value_Type:类型
Cmp_Fn:自定义比较器
Tag:堆的类型。可以是
binary_heap_tag(二叉堆)binomial_heap_tag(二项堆)rc_binomial_heap_tag pairing_heap_tag(配对堆)thin_heap_tag
Allocator:不用管
使用
相比STL中的priority_queue,可以
用begin()和end()获取迭代器从而遍历
删除单个元素
void erase(point_iterator)
增加或减少某一元素的值
void modify(point_iterator, const_reference)
合并,把other合并到*this,并把other清空
void join(priority_queue &other)
性能分析
五种操作:push、pop、modify、erase、join
pairing_heap_tag:push和join
binary_heap_tag:只支持push和pop,均为均摊
binomial_heap_tag:push为均摊
rc_binomial_heap_tag:push为
thin_heap_tag:push为
不支持不是不能用,而是用起来很慢
黑科技演示
#include <cstdio>#include <cstring>#include <algorithm>#include <ext/pb_ds/priority_queue.hpp>using namespace __gnu_pbds;inline int read(){ int x = 0; int v = 1, c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if(c == '-') v = -1; for(;c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0'; return x * v;}template<typename T>inline void write(T x, int ch = 10){ int s[20], t = 0; if(x < 0) { x = -x; putchar('-'); } do s[t++] = x % 10; while(x /= 10); while(t--) putchar('0' + s[t]); putchar(ch);}const int maxn = 100005;int n, m, v[maxn];int fa[maxn];priority_queue<int> q[maxn];int getfa(const int &x){ return fa[x] == x ? x : fa[x] = getfa(fa[x]);}void input(){ for(int i = 1; i <= n; ++i) { fa[i] = i; v[i] = read(); q[i].clear(); q[i].push(v[i]); } m = read();}void solve(){ register int x, y, z; for(int i = 1; i <= m; ++i) { x = getfa(read()); y = getfa(read()); if(x == y) puts("-1"); else { z = q[x].top(); q[x].pop(); q[x].push(z >> 1); z = q[y].top(); q[y].pop(); q[y].push(z >> 1); fa[y] = x; q[x].join(q[y]); write(q[x].top()); } }}int main(){#ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);#endif while(~scanf("%d", &n)) { input(); solve(); }#ifndef ONLINE_JUDGE fclose(stdin), fclose(stdout);#endif return 0;}
- zoj2334-Monkey King(超时)
- 【zoj2334】【左偏树】Monkey King
- ZOJ2334-Monkey King【二项堆】
- 【ZOJ2334】Monkey King
- ZOJ2334 HDU1512 Monkey King,左偏树
- ZOJ2334 Monkey King 左偏树+并查集
- ZOJ2334 Monkey King 【左偏树模板题】
- ZOJ2334 Monkey King 并查集 STL
- zoj2334 Monkey King , 并查集,可并堆,左偏树
- [HDU1512/ZOJ2334]Monkey King-左偏树-可合并堆
- hdu 1512 Monkey King
- zju 2334 monkey king
- Monkey King zoj 2334
- zoj 2334 Monkey King
- ZOJ 2334 Monkey King
- ZOJ 2334 Monkey King
- ZOJ 2334 Monkey King
- 【HDU 1512】Monkey King
- uva 120 Stacks of Flapjacks(练习deque)
- UVA - 1161 Objective: Berlin(最大流+时序模型)
- POJ1635(Subway tree systems)
- C++类构造函数初始化列表
- c++ 构造函数初始化列表
- 【ZOJ2334】Monkey King
- Oracle设置表中自增字段
- php动态调用函数方法&&非关系数据库的优势
- HDU 3232 && UVA 12230 (简单期望)
- HDU 5400 Arithmetic Sequence(数学,容斥)
- 华为机试题:字符串最后一个单词的长度
- UVA - 11082 Matrix Decompressing(最大流+行列模型)
- 【DirectX 2D游戏编程基础】directx 精灵绘图的应用,锚点与变换
- DFS解八皇后问题