【Luogu】P3224永无乡(splay)
生活随笔
收集整理的這篇文章主要介紹了
【Luogu】P3224永无乡(splay)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
splay模板,啟發式合并(其實就是暴力插入)即可。
順便吐槽時限,帶垃圾回收而已……不至于最后一個點死活不讓過吧?
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #include<queue> #define maxn 100020 using namespace std; inline long long read(){long long num=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)){num=num*10+ch-'0';ch=getchar();}return num*f; }int CNT; struct Node{int val,size,e[2],fa,num; }tree[maxn*10]; int tot;struct Splay{int root;Splay(){root=0;}inline void update(int x){tree[x].size=tree[tree[x].e[0]].size+tree[tree[x].e[1]].size+1; }inline int iden(int x){ return x==tree[tree[x].fa].e[1]; }inline void connect(int x,int fa,int how){ tree[x].fa=fa; tree[fa].e[how]=x; }void rotate(int x){int y=tree[x].fa; int r=tree[y].fa;int sony=iden(x); int sonr=iden(y);if(root==y) root=x;int b=tree[x].e[sony^1];connect(b,y,sony);connect(y,x,sony^1);connect(x,r,sonr);update(y); update(x);}void splay(int pos,int to){to=tree[to].fa;while(tree[pos].fa!=to){if(tree[tree[pos].fa].fa==to) rotate(pos);elseif(iden(pos)==iden(tree[pos].fa)){rotate(tree[pos].fa);rotate(pos);}else{ rotate(pos); rotate(pos); }}}inline int create(int val,int num,int fa){tree[++tot]=(Node){val,1,{0,0},fa,num};return tot;}int build(int val,int num){if(root==0){root=create(val,num,0);return root;}int now=root;while(now){tree[now].size++;int nxt=val<tree[now].val?0:1;if(tree[now].e[nxt]==0){connect(create(val,num,now),now,nxt);update(now);return tot;}now=tree[now].e[nxt];}}void insert(int val,int num){int p=build(val,num);if(++CNT==50){splay(p,root);CNT=0;}}int rank(int val){if(tree[root].size<val) return -1;int now=root;while(1){if(tree[tree[now].e[0]].size+1==val) return tree[now].num;if(tree[tree[now].e[0]].size>=val) now=tree[now].e[0];else{val-=tree[tree[now].e[0]].size+1;now=tree[now].e[1];}}} }s[maxn];void pushtree(int now,int x){s[x].insert(tree[now].val,tree[now].num);if(tree[now].e[0]) pushtree(tree[now].e[0],x);if(tree[now].e[1]) pushtree(tree[now].e[1],x); }int father[maxn]; int w[maxn];int ufind(int x){if(father[x]!=x) father[x]=ufind(father[x]);return father[x]; }void unionn(int x,int y){x=ufind(x); y=ufind(y);if(tree[s[x].root].size<tree[s[y].root].size) swap(x,y);pushtree(s[y].root,x);father[y]=x; }int main(){int n=read(),m=read();for(int i=1;i<=n;++i){w[i]=read();father[i]=i;s[i].insert(w[i],i);}for(int i=1;i<=m;++i){int x=read(),y=read();unionn(x,y);}int p=read();for(int i=1;i<=p;++i){char c[10];scanf("%s",c);int x=read(),y=read();if(c[0]=='Q') printf("%d\n",s[ufind(x)].rank(y));else unionn(x,y);}return 0; }
?
轉載于:https://www.cnblogs.com/cellular-automaton/p/8358187.html
總結
以上是生活随笔為你收集整理的【Luogu】P3224永无乡(splay)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery 实战读书笔记之第四章:使用
- 下一篇: Linux如何查看进程、杀死进程、查看端