[BZOJ][平衡树+启发式合并][替罪羊树]2733: [HNOI2012]永无乡
2018-02-05 17:02
471 查看
2733: [HNOI2012]永无乡
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 4444 Solved: 2378
[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
HINT
Source
看看数据大小估一下复杂度2个log。然后就想到了平衡树+启发式合并,具体实现的话我用了替罪羊树。
为什么要用替罪羊树呢?因为可以进第一页啊
代码如下:
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 4444 Solved: 2378
[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
HINT
Source
看看数据大小估一下复杂度2个log。然后就想到了平衡树+启发式合并,具体实现的话我用了替罪羊树。
为什么要用替罪羊树呢?因为可以进第一页啊
代码如下:
#include<cstdio> #include<algorithm> using namespace std; const double alpha=0.75; inline char tc(void){ static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline int read(void){ int a=0;char c; while((c=tc())<'0'||c>'9'); while(c>='0'&&c<='9')a=a*10+c-'0',c=tc(); return a; } inline char gc(void){ char c; while((c=tc())=='\n'||c=='\r'||c==' '); return c; } int o,n,m,q,f[100001],v[100001],sum[100001],rt[100001],size[100001],ch[100001][2],que[100001],tot,*sgt; int queo[100001],cnt; int gf(int x){ return x==f[x]?x:f[x]=gf(f[x]); } inline void update(int x){ size[x]=1+size[ch[x][0]]+size[ch[x][1]]; } inline bool isbad(int x){ if(size[x]*alpha+5<max(size[ch[x][0]],size[ch[x][1]]))return 1; return 0; } void dfs(int x){ if(ch[x][0])dfs(ch[x][0]); que[++tot]=x; if(ch[x][1])dfs(ch[x][1]); } int build(int l,int r){ if(l>r)return 0; int mid=l+r>>1,x=que[mid]; size[x]=1, ch[x][0]=build(l,mid-1), ch[x][1]=build(mid+1,r); update(x); return x; } inline void rebuild(int *x){ tot=0,dfs(*x),*x=build(1,tot); return ; } void insert(int &x,int a){ int w=x; if(x==0){ x=a,ch[a][0]=ch[a][1]=0; update(a); return ; } if(v[a]<=v[x])insert(ch[x][0],a); else insert(ch[x][1],a); update(x); if(isbad(x))sgt=&x; return ; } void ins(int &x,int a){ sgt=NULL; insert(x,a); if(sgt)rebuild(sgt); } void dfs1(int x){ if(ch[x][0])dfs(ch[x][0]); queo[++cnt]=x; if(ch[x][1])dfs(ch[x][1]); } void merge(int a,int b){ a=gf(a),b=gf(b); if(a==b)return ; if(sum[a]>sum[b])swap(a,b); cnt=0,dfs1(rt[a]); for(int i=1;i<=cnt;++i)ins(rt[b],queo[i]); rt[a]=0,f[a]=b,sum[b]+=sum[a]; } int find(int x,int k,int sum){ if(size[x]<k)return -1; if(k<=size[ch[x][0]])return find(ch[x][0],k,sum+1); else if(k==size[ch[x][0]]+1)return x; else return find(ch[x][1],k-size[ch[x][0]]-1,sum+1); } int main(void){ register int i,x,y; n=read(),m=read(); for(i=1;i<=n;++i)v[i]=read(),f[i]=i,sum[i]=1,rt[i]=i,size[i]=1; for(i=1;i<=m;++i)x=read(),y=read(),merge(x,y); q=read(); while(q--) if(gc()=='B')x=read(),y=read(),merge(x,y); else x=read(),y=read(),printf("%d\n",find(rt[gf(x)],y,0)); return 0; }
相关文章推荐
- BZOJ 2733 HNOI 2012 永无乡 平衡树启发式合并
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- 【BZOJ 2733】【HNOI 2012】永无乡【treap启发式合并】
- bzoj 2733 [HNOI2012]永无乡 splay启发式合并
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
- BZOJ[2733][HNOI2012]永无乡 Splay启发式合并
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
- BZOJ 2733 [HNOI2012] 永无乡 [splay+启发式合并做法]
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- 【BZOJ 2733】 [HNOI2012]永无乡|Splay启发式合并
- BZOJ 2733 [HNOI 2012] 线段树合并 解题报告
- BZOJ 2733 [HNOI2012]永无乡 可持久化线段树合并
- [BZOJ] 2733: [HNOI2012]永无乡 #线段树合并+并查集