zoj 2334 分类: zoj templa...
2015-08-11 23:12
211 查看
原文链接:https://www.geek-share.com/detail/2650305921.html
可并堆,左偏树,这是神犇“顺手学的东西”
以下是左偏树的合并操作代码。
int merge(int x,int y) { //p[i] 结点i的权值,这里是维护大根堆 //d[i] 在i的子树中,i到叶子结点的最远距离. if(!x) return y; if(!y) return x; if(p[x] < p[y]) std::swap(x, y); r[x] = merge(r[x], y); if(r[x]) fa[r[x]] = x; if(d[l[x]] < d[r[x]]) std::swap(l[x], r[x]);//调整树的结构,使其满足左偏性质 d[x] = d[r[x]] + 1; return x; }
这个题还是比较直白的。。。
时间复杂度:O(m∗log2n)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <string> #include <map> #include <vector> #include <stack> #include <queue> #include <utility> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]); } const int maxn = 1e5 + 50 , maxm = maxn, Nya = -1; int n, m, p[maxn]; int l[maxn], r[maxn], fa[maxn], d[maxn]; void init() { memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); memset(fa, 0, sizeof(fa)); memset(d, 0, sizeof(d)); for(int i = 1; i <= n; i++) read(p[i]); read(m); } int merge(int x,int y) { if(!x) return y; if(!y) return x; if(p[x] < p[y]) std::swap(x, y); r[x] = merge(r[x], y); if(r[x]) fa[r[x]] = x; if(d[l[x]] < d[r[x]]) std::swap(l[x], r[x]); d[x] = d[r[x]] + 1; return x; } int root(int x) { while(fa[x]) x = fa[x]; return x; } int dec(int t) { int L = l[t], R = r[t]; fa[L] = fa[R] = 0; l[t] = r[t] = d[t] = 0; p[t] >>= 1; return merge(merge(L, R), t); } void solve() { int u, v, ans; d[0] = Nya; while(m--) { read(u), read(v); u = root(u), v = root(v); ans = (u == v) ? Nya : p[merge(dec(u), dec(v))]; write(ans), puts(""); } } int main() { #ifndef ONLINE_JUDGE freopen("2334.in","r",stdin); freopen("2334.out","w",stdout); #endif while(scanf("%d", &n) != EOF) init(), solve(); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
转载于:https://www.cnblogs.com/dashgua/p/4722943.html
相关文章推荐
- zoj 2334 分类: zoj templates 2015-08-11 23:12 2人阅读 评论(0) 收藏
- ZOJ 题目分类
- ZOJ题目分类(转)
- POJ ZOJ题目分类
- ZOJ - 3985 - String of CCPC (分类讨论)
- ZOJ题目分类
- ZOJ 题目分类,学校的一个巨巨做的。
- POJ,ZOJ题目分类(多篇整合版,分类很细致,全面)
- ZOJ POJ 题目分类
- zoj--题目分类
- ZOJ 2334 Monkey King 可并堆左偏树
- zoj 3480 Duck Typing(模拟,分类讨论,读题)
- ZOJ 2334 Monkey King
- zoj、poj 题目分类
- zoj浙大acm题目分类整理
- ZOJ POJ题目分类
- zoj--题目分类
- zoj 2334
- ZOJ 2334 Monkey King 可并堆左偏树
- ZOJ水题分类