最近在学平衡树(Splay),想过一道模版题,但是我太弱了,老是写炸,于是想了一种方法代替平衡树,代码长度也十分优秀。
好了,不BB了,让我来讲一下我想出来的方法吧。
首先,我们分析一下Splay吧,思路比较简单,主要是rotate有点难理解其他都和BST差不多,但是代码实现起来有点麻烦,细节也比较多。
对于这道模版题,我的思路是把插入的数都补位,补到10位数(其实只用补到8位),然后把它当作字符串一样插入字典树中,这样就可以保证树的高度是10,不会退化,然后就很爽了♂。
对了,还有要处理负数,这里我就直接用了一个很暴力的方法,加了个偏移量。
详情可以参照我的代码(好像代码风格有点丑):
#include<bits/stdc++.h> using namespace std; const int N = 1000005; const int PY = 10000000; int ch[N][10],gs,cnt[N],n,size[N]; void insert(string x){ int p=0; for(int i=0;i<x.length();i++){ if(ch[p][x[i]-'0']==0) ch[p][x[i]-'0']=++gs; p=ch[p][x[i]-'0']; size[p]++; } cnt[p]++; } void del(string x){ int p=0; for(int i=0;i<x.length();i++){ p=ch[p][x[i]-'0']; size[p]--; } cnt[p]--; } int find_rank(string x){ int p=0,ret=0; for(int i=0;i<x.length();i++){ for(int j=0;j<x[i]-'0';j++){ if(ch[p][j])ret+=size[ch[p][j]]; } p=ch[p][x[i]-'0']; } return ret; } int find_rt(string x){ int p=0,ret=0; for(int i=0;i<x.length();i++){ for(int j=0;j<x[i]-'0';j++){ if(ch[p][j])ret+=size[ch[p][j]]; } p=ch[p][x[i]-'0']; } return cnt[p]; } int find_x(int x){ int p=0; string ans; for(int i=0;i<10;i++){ for(int j=0;j<10;j++){ if(ch[p][j]){ if(size[ch[p][j]]<x) x-=size[ch[p][j]]; else {p=ch[p][j];ans=ans+char(j+'0');break;} } } } string anss=""; int o=0; for(int i=1;i<=9;i++) if(ans[i]!='0') {o=i;break;} for(int i=o;i<=9;i++) anss=anss+ans[i]; int s=0; for(int i=0;i<anss.length();i++) s=s*10+anss[i]-'0'; s=s-PY; return s; } string x,xx; int c,ss; int main(){ ios::sync_with_stdio(false); cin>>n; while(n--){ cin>>c; cin>>x; ss=0; for(int i=0;i<x.length();i++) if(x[i]!='-')ss=ss*10+x[i]-'0'; if(x[0]=='-') ss=-ss; ss=ss+PY; int o=ss; x=""; while(o){ x=char(o%10+'0')+x; o/=10; } ss-=PY; xx=""; for(int i=0;i<x.size();i++) xx=xx+x[i]; while(xx.size()<9){ xx="0"+xx; } xx="0"+xx; if(c==1) insert(xx); if(c==2) del(xx); if(c==3) cout<<find_rank(xx)+1<<endl; if(c==4) cout<<find_x(ss)<<endl; if(c==5) insert(xx),cout<<find_x(find_rank(xx)+1-1)<<endl,del(xx); if(c==6) insert(xx),cout<<find_x(find_rank(xx)+1+find_rt(xx))<<endl,del(xx); } return 0; }
这一个方法感觉可拓展性不强,欢迎大家讨论(>_<)