https://www.lydsy.com/JudgeOnline/problem.php?id=2733

网上清一色的合并线段树题解,我又不会,只能自己胡来,没想到Rush过去了

永无乡包含 n 座岛,编号从  到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用  到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含  座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。 

Input
输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 %的数据 n≤,q≤ 对于 %的数据 n≤,m≤n,q≤ Output
对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-。 Sample Input Q
Q
B
B
Q
Q
Q
Sample Output
-

题意

这是一个只有建桥没有拆桥的操作,很显然可以离线重新排序,将之后会被建桥的区间连在一起,保证之后每次操作都是连续的一个区间。

然后发现就是维护一个区间K小,上主席树rush!rush!rush!就过了

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
int val[maxn];
int nxt[maxn],ed[maxn];
int fa[maxn];
void init(){
For(i,,N){
ed[i] = i;
nxt[i] = -;
fa[i] = i;
}
}
int find(int p){
return p == fa[p]?p:fa[p] = find(fa[p]);
}
void Union(int p,int q){
int fp = find(p),fq = find(q);
if(fp == fq) return;
nxt[ed[fp]] = fq;
ed[fp] = ed[fq];
fa[fq] = fp;
}
struct Node{
int op,x,y;
Node(int op = ,int x = ,int y = ):op(op),x(x),y(y) {}
}node[];
int Index[maxn],tot;
int T[maxn],lson[maxn * ],rson[maxn * ],c[maxn * ];
int build(int l,int r){
int root = tot++;
c[root] = ;
if(l != r){
int m = (l + r) >> ;
lson[root] = build(l,m);
rson[root] = build(m + ,r);
}
return root;
}
int update(int root,int pos,int val){
int newroot = tot++,tmp = newroot;
c[newroot] = c[root] + val;
int l = ,r = N;
while(l < r){
int m = (l + r) >> ;
if(pos <= m){
lson[newroot] = tot++;
rson[newroot] = rson[root];
newroot = lson[newroot];
root = lson[root];
r = m;
}else{
rson[newroot] = tot++;
lson[newroot] = lson[root];
newroot = rson[newroot];
root = rson[root];
l = m + ;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int query(int left_root,int right_root,int k){
int l = ,r = N;
while(l < r){
int m = (l + r) >> ;
if(c[lson[left_root]] - c[lson[right_root]] >= k){
r = m;
left_root = lson[left_root];
right_root = lson[right_root];
}else{
l = m + ;
k -= c[lson[left_root]] - c[lson[right_root]];
left_root = rson[left_root];
right_root = rson[right_root];
}
}
return l;
}
int id[maxn];
PII st[maxn];
int POS[maxn];
int main()
{
Sca2(N,M);
For(i,,N){
Sca(val[i]);
id[val[i]] = i;
}
init();
For(i,,M){
Sca2(st[i].fi,st[i].se);
Union(st[i].fi,st[i].se);
}
int K; Sca(K);
For(i,,K){
char op[]; scanf("%s",op);
Sca2(node[i].x,node[i].y);
if(op[] == 'B'){
node[i].op = ;
Union(node[i].x,node[i].y);
}else{
node[i].op = ;
}
}
int cnt = ;
For(i,,N){
if(i == fa[i]){
for(int j = i; ~j ; j = nxt[j]){
Index[++cnt] = j;
POS[j] = cnt;
}
}
}
T[N + ] = build(,N);
for(int i = N; i ; i --){
T[i] = update(T[i + ],val[Index[i]],);
}
init();
For(i,,M) Union(st[i].fi,st[i].se);
for(int i = ; i <= K ; i ++){
if(node[i].op == ){
Union(node[i].x,node[i].y);
}else{
int t = find(node[i].x);
int l = POS[t];
int r = POS[ed[t]];
int k = node[i].y;
//cout << l << " " << r << " " << k << endl;
if(k > r - l + || k < ){
puts("-1");
continue;
}
Pri(id[query(T[l],T[r + ],k)]);
}
}
#ifdef VSCode
system("pause");
#endif
return ;
}

bzoj2733 离线+并查集+主席树的更多相关文章

  1. 洛谷P3402 【模板】可持久化并查集 [主席树,并查集]

    题目传送门 可持久化并查集 n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 ...

  2. BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3545 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

  3. BZOJ3551 [ONTAK2010]Peaks加强版 kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3551 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

  4. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  5. 【bzoj5133】[CodePlus2017年12月]白金元首与独舞 并查集+矩阵树定理

    题目描述 给定一个 $n\times m$ 的方格图,每个格子有 ↑.↓.←.→,表示从该格子能够走到相邻的哪个格子.有一些格子是空着的,需要填上四者之一,需要满足:最终的方格图中,从任意一个位置出发 ...

  6. [bzoj1015](JSOI2008)星球大战 starwar(离线+并查集)

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武 器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通 ...

  7. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...

  8. ACM学习历程—Hihocoder 1291 Building in Sandbox(dfs && 离线 && 并查集)

    http://hihocoder.com/problemset/problem/1291 前几天比较忙,这次来补一下微软笔试的最后一题,这题是这次微软笔试的第四题,过的人比较少,我当时在调试B题,没时 ...

  9. HDU5441 Travel 离线并查集

    Travel Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, ...

随机推荐

  1. fftshift

    说明:本文为转载http://blog.csdn.net/myathappy/article/details/51344618 Matlab fftshift 详解 一.实信号情况 因为实信号以fs为 ...

  2. Xamarin + MvvmCross 安装 Part 1

    前言 最近,由于工作需要,公司准备开发移动端APP.临近年底,公司不准备大面招人,由于公司一直基于.net平台进行开发,本人自告奋勇,准备先用xamarin做下移动开发.开始了在网上不停的google ...

  3. 提交已经注入文件的表单给后台上传图片 使用ajaxsubmit

  4. 51Nod 1381 硬币游戏

    参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6445369.html 1381 硬币游戏 基准时间限制:1 秒 空间限制:131072 KB 分值 ...

  5. Java大数练习

    大数阶乘 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=28 import java.io.*; import java.util.*; ...

  6. ☆ [POJ1021] Intervals 「差分约束」

    传送门 >Here< 题意:给出N段区间,并告诉你每段区间里有几个数(一个位置只能放一个数) 问总共至少有几个数 解题思路 差分约束题,本蒟蒻也是第一次做差分约束题…… 所谓差分约束,常常 ...

  7. 【BZOJ5119】【CTT2017】生成树计数 DP 分治FFT 斯特林数

    CTT=清华集训 题目大意 有\(n\)个点,点权为\(a_i\),你要连接一条边,使该图变成一颗树. 对于一种连边方案\(T\),设第\(i\)个点的度数为\(d_i\),那么这棵树的价值为: \[ ...

  8. 【GZOI2015】石子游戏 博弈论 SG函数

    题目大意 有\(n\)堆石子,两个人可以轮流取石子.每次可以选择一堆石子,做出下列的其中一点操作: 1.移去整堆石子 2.设石子堆中有\(x\)个石子,取出\(y\)堆石子,其中\(1\leq y&l ...

  9. 「UVA10766」Organising the Organisation(生成树计数)

    BUPT 2017 Summer Training (for 16) #6C 题意 n个点,完全图减去m条边,求生成树个数. 题解 注意可能会给重边. 然后就是生成树计数了. 代码 #include ...

  10. 【bzoj3456】城市规划(多项式求逆+dp)

    Description 求\(~n~\)个点组成的有标号无向连通图的个数.\(~1 \leq n \leq 13 \times 10 ^ 4~\). Solution 这道题的弱化版是poj1737, ...