Splay(单点修改+查询)
生活随笔
收集整理的這篇文章主要介紹了
Splay(单点修改+查询)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
僅供參考。。。
#include<bits/stdc++.h> using namespace std;char readc(){static char buf[100000], *l=buf,*r=buf;if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);if (l==r) return EOF;else return *l++; }int read(){int x=0,f=1;char ch=readc();while (!isdigit(ch)) { if (ch=='-') f=-1; ch=readc();}while (isdigit(ch)) x=x*10+ch-48,ch=readc();return x*f; }namespace splay {const int MAXN=100000+11;int fa[MAXN],ch[MAXN][2],val[MAXN],siz[MAXN],num[MAXN],root,cnt;void clear(int x) {fa[x]=val[x]=siz[x]=num[x]=ch[x][0]=ch[x][1]=0;}void update(int x) {siz[x]=(ch[x][0] ? siz[ch[x][0]]:0)+(ch[x][1] ? siz[ch[x][1]]:0)+num[x];}int succ() {int x=ch[root][1];while (ch[x][0]) x=ch[x][0];return val[x];}int succ_id() {int x=ch[root][1];while (ch[x][0]) x=ch[x][0];return x;}int pre() {int x=ch[root][0];while (ch[x][1]) x=ch[x][1];return val[x];}int pre_id() {int x=ch[root][0];while (ch[x][1]) x=ch[x][1];return x;}void rotate(int x) {int y=fa[x],z=fa[y],d=(ch[y][1]==x);ch[y][d]=ch[x][d^1];fa[ch[x][d^1]]=y;ch[x][d^1]=y;fa[y]=x,fa[x]=z;if (z)ch[z][ch[z][1]==y]=x;update(y);update(x);}void splay(int x) {for (int y; y=fa[x]; rotate(x))if (fa[y])rotate((x==ch[y][0])^(y==ch[fa[y]][0]) ? x:y);root=x;}int find_val(int x) { // 查詢排名為 x 的數int y=root,tmp;while (true) {if (ch[y][0]&&siz[ch[y][0]]>=x) y=ch[y][0];else {tmp=(ch[y][0] ? siz[ch[y][0]]:0)+num[y];if (x<=tmp) return val[y];x-=tmp,y=ch[y][1];}}}int find_rank(int x) { // 查詢 x 數的排名int y=root,tmp=0;while (true){if (x<val[y]) y=ch[y][0];else {tmp+=(ch[y][0] ? siz[ch[y][0]]:0);if (x==val[y]){splay(y);return tmp+1;}tmp+=num[y],y=ch[y][1];}}}void insert(int k) {int x=root;if (!x) {root=x=++cnt,ch[x][0]=ch[x][1]=fa[x]=0,val[x]=k,num[x]=siz[x]=1;return;}int y=x,z=0;while (true) {if (val[y]==k) {num[y]++;update(y),update(z);splay(y);break;}z=y,y=ch[y][val[y]<k];if (!y) {val[y=++cnt]=k;num[y]=siz[y]=1;ch[y][0]=ch[y][1]=0;fa[y]=x;ch[x][val[x]<k]=y;break;}x=y;}splay(y);}void delt(int k) {find_rank(k);int x=root;if (!x)return;if (num[x]>1) {num[x]--,siz[x]--;return;}if (!ch[x][0]&&!ch[x][1]) {clear(x);root=0;return;}if (!ch[x][0]||!ch[x][1]) {int y=max(ch[x][0],ch[x][1]);root=y,fa[y]=0;clear(x);return;}int tmp=pre_id();splay(tmp);fa[ch[x][1]]=tmp;ch[tmp][1]=ch[x][1];clear(x);update(tmp);}} using namespace splay;int main() {int n=read();while (n--) {int opt=read(),x=read();switch(opt) {case 1: insert(x); break;case 2: delt(x); break;case 3: printf("%d\n",find_rank(x)); break;case 4: printf("%d\n",find_val(x)); break;case 5: insert(x),printf("%d\n",pre()),delt(x); break;case 6: insert(x),printf("%d\n",succ()),delt(x); break;}}return 0; }?
轉載于:https://www.cnblogs.com/QingCai-DCF/p/9529088.html
總結
以上是生活随笔為你收集整理的Splay(单点修改+查询)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 373. Find K Pairs wi
- 下一篇: MySql采用range分区可提升查询效