标签:
推荐黄嘉泰的线段树合并
HNOI永无乡
#include <stdio.h> #define maxn 100010 int n, m, id[maxn]; struct Edge{int to, nxt;}edge[maxn << 1]; int h[maxn], cnt; void add(int u, int v){ edge[++ cnt] = (Edge){v, h[u]}; h[u] = cnt; edge[++ cnt] = (Edge){u, h[v]}; h[v] = cnt; } int root[maxn], val[maxn]; bool vis[maxn]; int fa[maxn]; int getfa(int x){return x == fa[x] ? x : fa[x] = getfa(fa[x]);} #define TREE 5000010 int lc[TREE], rc[TREE], size[TREE], Size; void insert(int& rt, int l, int r, int x){ if(!rt)rt = ++ Size; size[rt] ++; if(l == r)return; int mid = l + r >> 1; if(x <= mid)insert(lc[rt], l, mid, x); else insert(rc[rt], mid+1, r, x); } int merge(int x, int y){ if(x == 0 || y == 0)return x + y; lc[x] = merge(lc[x], lc[y]); rc[x] = merge(rc[x], rc[y]); size[x] = size[lc[x]] + size[rc[x]]; return x; } int ask(int rt, int l, int r, int k){ if(l == r)return id[l]; int mid = l + r >> 1; if(k <= size[lc[rt]]) return ask(lc[rt], l, mid, k); k -= size[lc[rt]]; return ask(rc[rt], mid+1, r, k); } int main(){ scanf("%d%d", &n, &m); static int w[maxn]; for(int i = 1; i <= n; i ++) scanf("%d", &val[i]), id[val[i]] = i; int u, v; for(int i = 1; i <= n; i ++)fa[i] = i; for(int i = 1; i <= m; i ++){ scanf("%d%d", &u, &v); u = getfa(u), v = getfa(v); fa[getfa(v)] = getfa(u); } for(int i = 1; i <= n; i ++) insert(root[getfa(i)], 1, n, val[i]); int test; char cmd[2]; scanf("%d", &test); while(test --){ scanf("%s", cmd); if(cmd[0] == ‘Q‘){ scanf("%d%d", &u, &v), u = getfa(u); if(size[root[u]] < v){puts("-1");continue;} printf("%d\n", ask(root[u], 1, n, v)); } else{ scanf("%d%d", &u, &v); u = getfa(u), v = getfa(v); if(u == v)continue; root[u] = merge(root[u], root[v]); fa[getfa(v)] = getfa(u); } } return 0; }
[BZOJ 3702]二叉树
#include <bits/stdc++.h> #define maxn 400010 #define TREE 5000010 using namespace std; int n, son[maxn][2], w[maxn], root[maxn]; int cnt; int get_tree(){ int x = ++ cnt, a; scanf("%d", &a); if(a)w[x] = a; else{ son[x][0] = get_tree(); son[x][1] = get_tree(); } return x; } typedef long long ll; ll sum1, sum2, ans, sz[TREE]; int lc[TREE], rc[TREE], tr_cnt; int merge(int x, int y){ if(x == 0 || y == 0)return x + y; sum1 += sz[lc[x]] * sz[rc[y]]; sum2 += sz[lc[y]] * sz[rc[x]]; lc[x] = merge(lc[x], lc[y]); rc[x] = merge(rc[x], rc[y]); sz[x] = sz[lc[x]] + sz[rc[x]]; return x; } void insert(int &rt, int l, int r, int x){ rt = ++ tr_cnt; sz[rt] = 1; if(l == r)return; int mid = l + r >> 1; if(x <= mid) insert(lc[rt], l, mid, x); else insert(rc[rt], mid+1, r, x); } void dfs(int x){ if(son[x][0] && son[x][1]){ dfs(son[x][0]); dfs(son[x][1]); sum1 = sum2 = 0; root[x] = merge(root[son[x][0]], root[son[x][1]]); ans += min(sum1, sum2); } else insert(root[x], 1, n, w[x]); } int main(){ scanf("%d", &n); int root = get_tree(); dfs(root); printf("%lld\n", ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/Candyouth/p/5487069.html