zoukankan      html  css  js  c++  java
  • 【NOI】2004 郁闷的出纳员

    【算法】平衡树(treap)

    【题解】

    treap知识见数据结构

    解法,具体细节见程序。

    #include<cstdio>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    const int maxn=100010;
    struct cyc{int l,r,rnd,s,num;}t[maxn*3];
    int n,sz,low,root,delta;
    void rturn(int &tt)
    {
        int k=t[tt].l;
        t[tt].l=t[k].r;
        t[k].r=tt;
        t[k].s=t[tt].s;
        t[tt].s=t[t[tt].l].s+t[t[tt].r].s+1;
        tt=k;
    }
    void lturn(int &tt)
    {
        int k=t[tt].r;
        t[tt].r=t[k].l;
        t[k].l=tt;
        t[k].s=t[tt].s;
        t[tt].s=t[t[tt].l].s+t[t[tt].r].s+1;
        tt=k;
    }
    void insert(int &k,int x)
    {
        if(k==0)
         {
             k=++sz;
             t[k].rnd=rand();
             t[k].s=1;//s表示该子树的节点个数(含本身) 
             t[k].num=x;
             return;
         }
        t[k].s++;
        if(x<t[k].num)
         {
             insert(t[k].l,x);
             if(t[t[k].l].rnd<t[k].rnd)rturn(k);
         }
        else
         {
             insert(t[k].r,x);
             if(t[t[k].r].rnd<t[k].rnd)lturn(k);
         }
    }
    int del(int &k,int x)
    {
        int sum=0;
        if(k==0)return 0;
        if(x>t[k].num){sum=t[t[k].l].s+1;k=t[k].r;return sum+del(k,x);}//直接将根从k变为k的右子树,由于&的传递效果,相当于直接废了左子树和根节点,把右子树接上去。 
         else{sum=del(t[k].l,x);t[k].s-=sum;return sum;} 
    }
    int find(int k,int x)
    {
        if(t[t[k].l].s+1==x)return(t[k].num+delta);
        if(x<=t[t[k].l].s)return(find(t[k].l,x));
         else return(find(t[k].r,x-t[t[k].l].s-1));
    }
    int main()
    {
        scanf("%d%d",&n,&low);
        srand(time(0));
        int ans=0;
        for(int i=1;i<=n;i++)
         {
             char c=getchar();int rd;
             while(c<'A'||c>'Z')c=getchar();
             scanf("%d",&rd);
             if(c=='I')if(rd>=low)insert(root,rd-delta);
             if(c=='A')delta+=rd;
             if(c=='S'){delta-=rd;ans+=del(root,low-delta);}
             if(c=='F')
             {
                 if(t[root].s<rd)printf("-1
    ");
                  else printf("%d
    ",find(root,t[root].s-rd+1));
             } 
         }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Angular1.0
    当今流行的 React.js 适用于怎样的 Web App?
    bower的权限问题
    淡定啊淡定
    JBoss for luna
    JQuery的二维码插件
    今天学人家玩云主机
    laravel5.2/laravel5.3入门指南 Windows 上快速安装并运行 Laravel 5.x
    验证mySqli扩展是否
    Amazon EC2 的名词解释
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6379934.html
Copyright © 2011-2022 走看看