日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

splay 模板 洛谷3369

發布時間:2023/12/18 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 splay 模板 洛谷3369 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

您需要寫一種數據結構(可參考題目標題),來維護一些數,其中需要提供以下操作:

插入 xx 數
刪除 xx 數(若有多個相同的數,因只刪除一個)
查詢 xx 數的排名(排名定義為比當前數小的數的個數 +1+1 。若有多個相同的數,因輸出最小的排名)
查詢排名為 xx 的數
求 xx 的前驅(前驅定義為小于 xx ,且最大的數)
求 xx 的后繼(后繼定義為大于 xx ,且最小的數)
輸入輸出格式

輸入格式:
第一行為 nn ,表示操作的個數,下面 nn 行每行有兩個數 optopt 和 xx , optopt 表示操作的序號( 1 \leq opt \leq 6 1≤opt≤6 )

輸出格式:
對于操作 3,4,5,63,4,5,6 每行輸出一個數,表示對應答案

輸入輸出樣例

輸入樣例#1: 復制
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
輸出樣例#1: 復制
106465
84185
492737
說明

時空限制:1000ms,128M

1.n的數據范圍: n \leq 100000 n≤100000

2.每個數的數據范圍: [-{10}^7, {10}^7][?10
7
,10
7
]

來源:Tyvj1728 原名:普通平衡樹

#include<iostream> #include<cstdio> #include<cstring>using namespace std; const int MAXN = 100005; const int inf = 0x7f7f7f7f;struct Node{int v,fa;int ch[2];int sum;int recy; }node[MAXN];int n,cnt,points;inline void update(int x){node[x].sum=node[node[x].ch[1]].sum+node[node[x].ch[0]].sum+node[x].recy; }inline bool jud(int x){return node[node[x].fa].ch[0]==x?0:1; }inline void connect(int x,int f,int son){node[x].fa=f;node[f].ch[son]=x; }inline void rotate(int x){int y=node[x].fa;int mroot=node[y].fa;int mrootson=jud(y);int yson=jud(x);int oth=node[x].ch[yson^1];connect(oth,y,yson);connect(y,x,(yson^1));connect(x,mroot,mrootson);update(y);update(x); }inline void splay(int at,int to){to=node[to].fa;while(node[at].fa!=to){int up=node[at].fa;if(node[up].fa==to) rotate(at);else if(jud(up)==jud(at)){rotate(up);rotate(at);}else{rotate(at);rotate(at);}} }inline int crepoint(int x,int f){node[++cnt].v=x;node[cnt].fa=f;node[cnt].sum=1;node[cnt].recy=1;return cnt; }inline void destroy(int x){node[x].v=node[x].fa=node[x].sum=node[x].recy=node[x].ch[0]=node[x].ch[1]=0;if(x==cnt) cnt--; }inline int find(int v){int now=node[0].ch[1];while(1){if(node[now].v==v){splay(now,node[0].ch[1]);return now;}int nxt=v<node[now].v?0:1;if(!node[now].ch[nxt]) return 0;now=node[now].ch[nxt];} }inline int build(int x){points++;if(cnt==0){node[0].ch[1]=1;crepoint(x,0);}else{int now=node[0].ch[1];while(1){node[now].sum++;if(x==node[now].v){node[now].recy++;return now;}int nxt=x<node[now].v?0:1;if(!node[now].ch[nxt]){crepoint(x,now);node[now].ch[nxt]=cnt;return cnt;}now=node[now].ch[nxt];}}return 0; }inline void push(int x){int add=build(x);splay(add,node[0].ch[1]); }inline void pop(int v){int deal=find(v);if(!deal) return;points--;if(node[deal].recy>1){node[deal].recy--;node[deal].sum--;return;}if(!node[deal].ch[0]){node[0].ch[1]=node[deal].ch[1];node[node[0].ch[1]].fa=0;}else{int lef=node[deal].ch[0];while(node[lef].ch[1]) lef=node[lef].ch[1];splay(lef,node[deal].ch[0]);int rig=node[deal].ch[1];connect(rig,lef,1);connect(lef,0,1);update(lef); }destroy(deal); }int rank(int x){int ans=0;int now=node[0].ch[1];while(1){if(node[now].v==x) return ans+node[node[now].ch[0]].sum+1;if(now==0) return 0;if(x<node[now].v) now=node[now].ch[0];else{ans+=node[node[now].ch[0]].sum+node[now].recy;now=node[now].ch[1];}}if(now) splay(now,node[0].ch[1]);return 0; }int atrank(int x){if(x>points) return -inf;int now=node[0].ch[1];while(1){int minn=node[now].sum-node[node[now].ch[1]].sum;if(x>node[node[now].ch[0]].sum && x<=minn) break;if(x<minn) now=node[now].ch[0];else{x=x-minn;now=node[now].ch[1];}}splay(now,node[0].ch[1]);return node[now].v; }inline int lower(int x){int now=node[0].ch[1];int res=-inf;while(now){if(node[now].v<x && node[now].v>res) res=node[now].v;if(x>node[now].v) now=node[now].ch[1];else now=node[now].ch[0];}return res; }inline int upper(int x){int now=node[0].ch[1];int res=inf;while(now){if(node[now].v>x && node[now].v<res) res=node[now].v;if(x<node[now].v) now=node[now].ch[0];else now=node[now].ch[1];}return res; }int main(){scanf("%d",&n);push(inf);push(-inf);for(register int i=1;i<=n;i++){int opt,x;scanf("%d%d",&opt,&x);if(opt==1) push(x);else if(opt==2) pop(x);else if(opt==3) printf("%d\n",rank(x)-1);else if(opt==4) printf("%d\n",atrank(x+1));else if(opt==5) printf("%d\n",lower(x));else printf("%d\n",upper(x));}return 0; }

總結

以上是生活随笔為你收集整理的splay 模板 洛谷3369的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。