2733: [HNOI2012]永无乡
Posted yinwuxiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2733: [HNOI2012]永无乡相关的知识,希望对你有一定的参考价值。
题解:
爬到了bzoj的数据哈哈哈哈
然后提交上去t了 自己测只有1秒多呀 不理解
然后这题目就是个线段树/平衡树合并裸题
来练一下线段树合并 据说是nlogn的
#include <bits/stdc++.h> using namespace std; const int N=2e5; #define rg register #define IL inline int n,m,fa[N],a[N],b[N],cnt,root[N],count2[N*15],ls[N*15],rs[N*15]; bool f[N]; int find(rg int x) { rg int tmp; if (fa[x]!=x) tmp=find(fa[x]); else return(x); fa[x]=tmp; return(tmp); } IL void link(rg int x,rg int y) { x=find(x),y=find(y); if (x!=y) fa[x]=y; } #define mid (h+t)/2 void insert(int &x,int goal,int h,int t) { if (!x) x=++cnt; count2[x]++; if (h==t) return; if (goal<=mid) insert(ls[x],goal,h,mid); else insert(rs[x],goal,mid+1,t); } int query(int x,int y,int h,int t) { if (h==t) if (y==1&&x!=0) return(h); else return(0); if (count2[ls[x]]<y) return(query(rs[x],y-count2[ls[x]],mid+1,t)); else return(query(ls[x],y,h,mid)); } int merge(int &x,int &y) { if (x==0) return(y); if (y==0) return(x); ls[x]=merge(ls[x],ls[y]); rs[x]=merge(rs[x],rs[y]); count2[x]=count2[ls[x]]+count2[rs[x]]; return(x); } int main() { freopen("noi.in","r",stdin); freopen("noi.out","w",stdout); ios::sync_with_stdio(false); cin>>n>>m; for (rg int i=1;i<=n;i++) cin>>a[i],b[a[i]]=i,fa[i]=i; for (rg int i=1;i<=m;i++) { int x,y; cin>>x>>y; link(x,y); } for (rg int i=1;i<=n;i++) { int x=find(i); insert(root[x],a[i],1,N); } int qt; cin>>qt; b[0]=-1; for (rg int i=1;i<=qt;i++) { int x,y; char cc; cin>>cc; cin>>x>>y; if (cc==‘Q‘) { x=find(x); int t=query(root[x],y,1,N); cout<<b[query(root[x],y,1,N)]<<endl; } if (cc==‘B‘) { x=find(x); y=find(y); if (x!=y) { fa[x]=y; root[y]=merge(root[x],root[y]); } } } return 0; }
以上是关于2733: [HNOI2012]永无乡的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ] 2733: [HNOI2012]永无乡 #线段树合并+并查集
Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并