标签:har getc pre nbsp 开始 put div col mes
zip//右旋
void zip(int &k)//右旋 { int y=lc(k); lc(k)=rc(y); rc(y)=k; s(y)=s(k); upt(k); k=y; }
zap//左旋
void zap(int &k)//左旋 { int y=rc(k); rc(k)=lc(y); lc(y)=k; s(y)=s(k); upt(k); k=y; }
insert//插入
1.终止,添加单点信息
2.修改size
3.向下插入(先插后旋)
void Insert(int &k,int &key)//插入 { if(!k) { k=++nt,v(k)=key,p(k)=rand();//从1开始 s(k)=c(k)=1,lc(k)=rc(k)=0; return; } s(k)++; if(v(k)==key) c(k)++; else if(v(k)>key) { Insert(lc(k),key); if(p(lc(k))<p(k)) zip(k); } else{ Insert(rc(k),key); if(p(rc(k))<p(k)) zap(k); } return; }
Delete//删除
1.查找到,删除(先旋后删)
2.修改size
3.向下查找
void Delete(int &k,int &key)//删除 { if(v(k)==key) { if(c(k)>1) c(k)--,s(k)--; else if(!lc(k) or !rc(k)) k=lc(k)+rc(k); else if(p(lc(k))<p(rc(k))) zip(k),Delete(k,key); else zap(k),Delete(k,key); return; } s(k)--; if(key<v(k)) Delete(lc(k),key); else Delete(rc(k),key); return; }
queryrank//查询此元素的名次(如有重复元素,返回最高名次)
int queryrank(int &key)//查询此元素的名次(如有重复元素,返回最高名次) { int k=rt,re=0; while(k) { if(key==v(k)) return re+s(lc(k))+1; else if(key<v(k)) k=lc(k); else re+=s(lc(k))+c(k),k=rc(k); } return re; }
querykth//查询第k小的元素
int querykth(int k)//查询第k小的元素 { int x=rt; while(x) { if(k>s(lc(x)) and k<=s(lc(x))+c(x)) return v(x); else if(k<=s(lc(x))) x=lc(x); else k-=s(lc(x))+c(x),x=rc(x); } return v(x); }
querypre//查询元素的前驱
int querypre(int &key)//查询元素的前驱 { int x=rt,re=2e9; while(x) { if(v(x)<key) re=v(x),x=rc(x); else x=lc(x); } return re; }
querysur//查询元素的后驱
int querysur(int &key)//查询元素的后驱 { int x=rt,re=2e9; while(x) { if(v(x)>key) re=v(x),x=lc(x); else x=rc(x); } return re; }
#include<iostream>//来个总代码(洛谷3369(https://www.luogu.org/problemnew/show/P3369)) #include<cstdio> #include<cstdlib> using namespace std; void upt(int &k); void zip(int &k);//右旋 void zap(int &k);//左旋 void Insert(int &k,int &key);//插入 void Delete(int &k,int &key);//删除 int queryrank(int &key);//查询此元素的名次(如有重复元素,返回最高名次) int querykth(int k);//查询第k小的元素 int querypre(int &key);//查询元素的前驱 int querysur(int &key);//查询元素的后驱 void read(int &x); void write(int x); struct node{ int lc,rc,key,priority,size,cnt; #define lc(k) a[k].lc #define rc(k) a[k].rc #define v(k) a[k].key #define p(k) a[k].priority #define s(k) a[k].size #define c(k) a[k].cnt }; node a[100050]; int nt=0,rt;//附属条件 int main() { int n; read(n); int q,s; for(int i=1;i<=n;i++) { read(q),read(s); if(q==1) Insert(rt,s); if(q==2) Delete(rt,s); if(q==3) write(queryrank(s)),putchar(‘\n‘); if(q==4) write(querykth(s)),putchar(‘\n‘); if(q==5) write(querypre(s)),putchar(‘\n‘); if(q==6) write(querysur(s)),putchar(‘\n‘); } return 0; } void upt(int &k) {s(k)=s(lc(k))+s(rc(k))+c(k);} void zip(int &k)//右旋 { int y=lc(k); lc(k)=rc(y); rc(y)=k; s(y)=s(k); upt(k); k=y; } void zap(int &k)//左旋 { int y=rc(k); rc(k)=lc(y); lc(y)=k; s(y)=s(k); upt(k); k=y; } void Insert(int &k,int &key)//插入 { if(!k) { k=++nt,v(k)=key,p(k)=rand();//从1开始 s(k)=c(k)=1,lc(k)=rc(k)=0; return; } s(k)++; if(v(k)==key) c(k)++; else if(v(k)>key) { Insert(lc(k),key); if(p(lc(k))<p(k)) zip(k); } else{ Insert(rc(k),key); if(p(rc(k))<p(k)) zap(k); } return; } void Delete(int &k,int &key)//删除 { if(v(k)==key) { if(c(k)>1) c(k)--,s(k)--; else if(!lc(k) or !rc(k)) k=lc(k)+rc(k); else if(p(lc(k))<p(rc(k))) zip(k),Delete(k,key); else zap(k),Delete(k,key); return; } s(k)--; if(key<v(k)) Delete(lc(k),key); else Delete(rc(k),key); return; } int queryrank(int &key)//查询此元素的名次(如有重复元素,返回最高名次) { int k=rt,re=0; while(k) { if(key==v(k)) return re+s(lc(k))+1; else if(key<v(k)) k=lc(k); else re+=s(lc(k))+c(k),k=rc(k); } return re; } int querykth(int k)//查询第k小的元素 { int x=rt; while(x) { if(k>s(lc(x)) and k<=s(lc(x))+c(x)) return v(x); else if(k<=s(lc(x))) x=lc(x); else k-=s(lc(x))+c(x),x=rc(x); } return v(x); } int querypre(int &key)//查询元素的前驱 { int x=rt,re=2e9; while(x) { if(v(x)<key) re=v(x),x=rc(x); else x=lc(x); } return re; } int querysur(int &key)//查询元素的后驱 { int x=rt,re=2e9; while(x) { if(v(x)>key) re=v(x),x=lc(x); else x=rc(x); } return re; } void read(int &x) { x=0; int i=1; char c=getchar(); while(c<‘0‘ or c>‘9‘) { if(c==‘-‘) i=-1; c=getchar(); } while(c>=‘0‘ and c<=‘9‘) { x=x*10+c-‘0‘; c=getchar(); } x*=i; } void write(int x) { if(x<0) putchar(‘-‘),x*=-1; if(x>9) write(x/10); putchar(x%10+‘0‘); }
标签:har getc pre nbsp 开始 put div col mes
原文地址:https://www.cnblogs.com/shzyk/p/9733448.html