地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733

题目:

2733: [HNOI2012]永无乡

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4059  Solved: 2167
[Submit][Status][Discuss]

Description

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

Input

输入文件第一行是用空格隔开的两个正整数 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

Output

对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。

Sample Input

5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3

Sample Output

-1
2
5
1
2
 
思路:
  启发式合并。
 /**************************************************************
Problem: 2733
User: weeping
Language: C++
Result: Accepted
Time:4908 ms
Memory:4436 kb
****************************************************************/ #include <bits/stdc++.h> using namespace std; #define lc ch[x][0]
#define rc ch[x][1] int n,m,q,f[]; int fd(int x)
{
return f[x]==x?x:f[x]=fd(f[x]);
} struct SplayTree
{ const static int maxn = 1e5 + ; int tot,root,ch[maxn][], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn]; inline void init( int x, int ky, int v = , int par = )
{
lc=rc=, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = , rev[x] = ;
} inline void init()
{
init( , , );
sz[] = ;
tot = root = ;
} inline void push_up(int x)
{
sz[x] = sz[lc] + sz[rc] + ;
} inline void reverse(int x)
{
rev[x] ^= , swap( lc, rc);
} inline void push_down(int x)
{
if(rev[x])
{
if(lc) reverse(lc);
if(rc) reverse(rc);
rev[x] = ;
}
} void rotate( int x)
{
int f = fa[x], gf = fa[f];
int t1 = (ch[f][] == x), t2 = (ch[gf][] == f);
if( gf ) ch[gf][t2] = x;
fa[x] = gf, ch[f][t1] = ch[x][^t1], fa[ch[f][t1]] = f;
ch[x][t1^] = f, fa[f] = x;
push_up( f ), push_up( x );
} void splay( int x, int tar )
{
for(int f = fa[x], gf = fa[f]; f != tar; rotate(x), f = fa[x], gf = fa[f])
if(gf != tar)
rotate( ((ch[f][] == x) == (ch[gf][] == f) )? f: x);
if( !tar ) root = x;
} void insert( int ky, int v)
{
int x = root, ls = root;
while(x)
{
push_down(x);
sz[x] ++, ls = x;
x = ch[x][ky > key[x]];
}
init( ++tot, ky, v, ls);
ch[ls][ky > key[ls]] = tot;
splay( tot, );
} int find( int ky)
{
int x = root;
while(x)
{
push_down(x);
if(key[x] == ky) break;
x = ch[x][ky > key[x]];
}
if(x) splay(x,);
else x = -;
return x;
} // Delete Root
void Delete()
{
if( !ch[root][] )
{
fa[ ch[root][] ] = ;
root = ch[root][];
}
else
{
int cur = ch[root][];
while( ch[cur][] ) cur = ch[cur][];
splay( cur, root );
ch[cur][] = ch[root][];
root = cur, fa[cur] = , fa[ch[root][]] = root;
push_up( root );
}
} int kth( int k)
{
int x = root;
if(sz[x] < k) return -;
while(x)
{
push_down(x);
if(k == sz[lc] + ) break;
if(k > sz[lc])
k -= sz[lc] + , x = rc;
else
x = lc;
}
if(x) splay(x,);
else x = -;
return x;
} int pred( void)
{
int x = root;
if(!x || !lc) return -;
x = lc;
while(rc) push_down(x), x = rc;
splay( x, );
return x;
} int succ( void)
{
int x = root;
if(!x || !rc) return -;
x = rc;
while(lc) push_down(x), x = lc;
splay( x, );
return x;
} void debug( int x )
{
if( !x ) return;
if(lc) debug( lc );
printf("%d ", key[x] );
if(rc) debug( rc );
} void qinsert(int y)
{
int x = root, ls = root, ky = key[y];
while(x)
ls = x, x = ch[x][ky > key[x]];
x = ls;
ch[x][ky > key[x]] = y,fa[y] = x, sz[y] = ;
splay(y, );
} void qmerge(int x)
{
if(!x) return;
int tl = lc, tr = rc;
lc = rc = ;
qmerge(tl);
qinsert(x);
qmerge(tr);
}
void merge(int u,int v)
{
if(u == v) return ;
if(sz[u]>sz[v]) swap(u,v);
f[u] = v, splay( v, );
qmerge(u);
}
} sp; int main(void)
{
scanf("%d%d",&n,&m);
for(int i=,x;i<=n;i++)
scanf("%d",&x),f[i]=i,sp.key[i]=x,sp.sz[i]=;
for(int i=,u,v;i<=m;i++)
scanf("%d%d",&u,&v),sp.merge(fd(u),fd(v));
scanf("%d",&q);
char op[];
for(int i=,x,y;i<=q;i++)
{
scanf("%s%d%d",op,&x,&y);
if(op[]=='B')
sp.merge(fd(x),fd(y));
else
sp.splay(x,),printf("%d\n",sp.kth(y));
}
return ;
}

bzoj2733: [HNOI2012]永无乡 启发式合并的更多相关文章

  1. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. BZOJ 2733 [HNOI2012]永无乡 - 启发式合并主席树

    Description 1: 查询一个集合内的K大值 2: 合并两个集合 Solution 启发式合并主席树板子 Code #include<cstdio> #include<cst ...

  3. bzoj2733: [HNOI2012]永无乡(splay)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3778  Solved: 2020 Description 永 ...

  4. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4108  Solved: 2195[Submit][Statu ...

  5. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  6. [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  7. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  8. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  9. bzoj2733: [HNOI2012]永无乡 线段树合并

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...

随机推荐

  1. Visual Studio 2015打开ASP.NET MVC的View提示"Object reference not set to an instance of an object"错误的解决方案

    使用Visual Studio 2013打开没有问题,但Visual Studio 2015打开cshtml就会提示"Object reference not set to an insta ...

  2. JAVA unicode转换成中文

    /** * * unicode 转换成 中文 * @param theString * @return */ public static String decodeUnicode(String the ...

  3. js的mime类型有哪些?

    js中的mime类型 常见类型 扩展名 类型/子类型 txt text/plain doc application/msword exe application/octet-stream pdf ap ...

  4. Shell转义字符与变量替换

    转义字符 含义 \\ 反斜杠 \a 警报,响铃 \b 退格(删除键) \f 换页(FF),将当前位置移到下页开头 \n 换行 \r 回车 \t 水平制表符(tab键)  \v 垂直制表符 vim te ...

  5. sklearn的快速使用

    传统的机器学习任务从开始到建模的一般流程是:获取数据 -> 数据预处理 -> 训练建模 -> 模型评估 -> 预测,分类.本文我们将依据传统机器学习的流程,看看在每一步流程中都 ...

  6. 9.12DjangoORM回顾和路由.

    2018-9-12 13:44:41 周末继续整理一下博客!不知不觉记了好多! 越努力越幸运! 永远不要高估自己! 关于反射的复习 # /usr/bin/env python # -*- coding ...

  7. SqlServer数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)

    查询表信息(表名/表描述) Value ) AS value FROM sysobjects a Where a.xtype = 'U' AND a.name <> 'sysdiagram ...

  8. poj1066 Treasure Hunt【计算几何】

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8192   Accepted: 3376 Des ...

  9. TACOTRON:端到端的语音合成

    tacotron主要是将文本转化为语音,采用的结构为基于encoder-decoder的Seq2Seq的结构.其中还引入了注意机制(attention mechanism).在对模型的结构进行介绍之前 ...

  10. 反面教材 构造构造 json 数据

    构造构造 json 数据 说说你们在项目中遇到过的最糟糕的代码 - V2EX https://www.v2ex.com/t/214099