首页 > 代码库 > 郁闷的出纳员 平衡二叉树
郁闷的出纳员 平衡二叉树
这是个经典问题;
用平衡二叉树维护,只不过节点需要多储存一个siz信息,表明在平衡树上的此节点的子节点数;
平衡树稍稍拓展一下的题目,对我而言,写平衡树的代码难度才是关键;
调试了几个小时,这种题目果然需要多练习;
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<cmath> 8 #include<ctime> 9 using namespace std;10 const int maxn=101000;11 const int inf=100000000;12 char ch;13 int n,minn=0,delet=0,x,sum=0,root=0,len=0,all=0;14 struct node{15 int m,v,siz;16 int ch[2];17 int cmp(int x){return m>x?0:1;}18 }e[maxn<<2];19 void countsiz(int &x,int d){20 int k=e[x].ch[d];21 e[x].siz=e[x].siz-e[k].siz+e[e[k].ch[d^1]].siz;22 e[k].siz=e[e[k].ch[d]].siz+e[x].siz+1;23 }24 void rotate(int &x,int d){25 countsiz(x,d);26 int k=e[x].ch[d];27 e[x].ch[d]=e[k].ch[d^1];28 e[k].ch[d^1]=x;29 x=k;30 }31 void insert(int &x,int m){32 if(x==0){x=++len;e[x].m=m;e[x].v=rand();e[x].siz=1;return;}33 int d=e[x].cmp(m);34 insert(e[x].ch[d],m);35 e[x].siz=e[e[x].ch[0]].siz+e[e[x].ch[1]].siz+1;36 if(e[e[x].ch[d]].v>e[x].v)rotate(x,d);37 }38 void found(int m){39 if(m<minn)return;40 all++;41 insert(root,m-delet);42 }43 void dfs(int &x){44 if(x==0)return;45 if(e[x].m+delet>=minn){dfs(e[x].ch[0]);e[x].siz=e[e[x].ch[0]].siz+e[e[x].ch[1]].siz+1;return;}46 if(e[x].m+delet<minn){47 if(e[x].ch[1]){48 rotate(x,1);49 dfs(x);50 if(x==0)return;51 for(int d=0;d<2;d++)if(e[e[x].ch[d]].v>e[x].v)rotate(x,d);52 e[x].siz=e[e[x].ch[0]].siz+e[e[x].ch[1]].siz+1;53 }54 else{55 sum+=e[x].siz;56 x=0;57 }58 }59 }60 void add(int x){61 delet+=x;62 if(x<0)dfs(root);63 }64 int dfs(int x,int k,int right){65 int r=e[x].ch[1];66 if(x==0)return -inf;67 if(right+e[r].siz==k)return e[x].m;68 if(right+e[r].siz>k)return dfs(r,k,right);69 if(right+e[r].siz<k)return dfs(e[x].ch[0],k,right+e[r].siz+1);70 }71 void find(int k){72 int p=dfs(root,k-1,0);73 printf("%d\n",p==-inf?-1:p+delet);74 }75 void work(){76 srand(time(0));77 scanf("%d%d",&n,&minn);78 while(n--){79 scanf(" %c %d",&ch,&x);80 if(ch==‘I‘)found(x);81 if(ch==‘A‘)add(x);82 if(ch==‘S‘)add(-x);83 if(ch==‘F‘)find(x);84 }85 cout<<sum<<endl;86 }87 int main(){88 work();89 }
郁闷的出纳员 平衡二叉树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。