zoukankan      html  css  js  c++  java
  • 郁闷的出纳员 平衡二叉树

    这是个经典问题;

    用平衡二叉树维护,只不过节点需要多储存一个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
    ",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 }
    View Code
  • 相关阅读:
    不要在构造中做太多事情,不然有时候会出现有意思的代码~
    对称加密和非对称加密
    关于WebAPI安全认证的问题
    Dojo和jQuery区别
    跨域访问解决方案:JSONP
    MyEclipse中提示SpringMVC的XML配置文件出错解决方法
    什么是跨域请求
    Hadoop的初步理解
    数据库读写分离的初步理解
    前端渲染和后端渲染
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5835674.html
Copyright © 2011-2022 走看看