zoukankan      html  css  js  c++  java
  • bzoj1503

    题解:

    splay题目

    维护一个splay

    加上一个数就枚举一下

    其实可以统一加

    注意:一开始进来的时候,如果k<min,那么这个人立马就会走人

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200005;
    int T,q,pre[N],size[N],c[N][2],n,f[N],root,z,tot,data[N],p[N],x;
    char s[3];
    void rot(int x)
    {
        int y=pre[x],k=(c[y][0]==x);
        size[y]=size[c[y][k]]+size[c[x][k]]+1;
        size[x]=size[c[x][!k]]+size[y]+1;
        c[y][!k]=c[x][k];
        pre[c[y][!k]]=y;
        pre[x]=pre[y];
        if(pre[y])c[pre[y]][c[pre[y]][1]==y]=x;
        c[x][k]=y;pre[y]=x;
    }
    void splay(int x,int g)
    {
        for(int y=pre[x];y!=g;rot(x),y=pre[x])
         if(pre[y]!=g)rot((x==c[y][0])==(y==c[pre[y]][0])?y:x);
        if(g==0)root=x;
    }
    void insert(int x)
    {
        int y=root;
        while(c[y][x>data[y]]) y=c[y][x>data[y]];
        data[++tot]=x;
        c[tot][0]=c[tot][1]=0;
        pre[tot]=y;
        if(y)c[y][x>data[y]]=tot;
        splay(tot,0);
    }
    void del(int x)
    {
        int y=root;
        while(data[y]!=x) y=c[y][x>data[y]];
        splay(y,0);
        y=c[root][1];
        bool b;
        if(!y) b=1,y=c[root][0];else b=0;
        while(c[y][b]) y=c[y][b];
        splay(y,root);
        c[y][b]=c[root][b];pre[c[root][b]]=y;pre[y]=0;root=y;
        size[y]=size[c[y][!b]]+size[c[y][b]];
    }
    int findkth(int x)
    {
        int y=root;
        while(x)
        if(size[c[y][0]]+1<x)x-=size[c[y][0]]+1,y=c[y][1];
        else if(size[c[y][0]]+1==x) return data[y];
        else y=c[y][0];
        return data[y];
    }
    int main()
    {
        scanf("%d%d",&T,&q);
        int pp=0;
        while (T--)
         {
             scanf("%s%d",&s,&x);
             if (s[0]=='A')
              {
                  z+=x;
                  for (int i=1;i<=n;i++)
                   if (!f[i]&&p[i]+z<q)
                    {
                        f[i]=1;
                        pp++;
                        del(p[i]);
                    }
              }
             if (s[0]=='S') 
              {
                  z-=x;
                  for (int i=1;i<=n;i++)
                   if (!f[i]&&p[i]+z<q)
                    {
                        f[i]=1;
                        pp++;
                        del(p[i]);
                    }              
              }
             if (s[0]=='I'&&x>=q)
             {
                  p[++n]=x-z;
                  insert(p[n]);
             } 
            if (s[0]=='F')
             if (n-pp<x)puts("-1");
             else printf("%d
    ",findkth(n-pp-x+1)+z); 
         }
        printf("%d",pp); 
    }
  • 相关阅读:
    【gtest/gmock】警告与报错集合
    【gtest/gmock】gmock:Mock的常用方法
    【C++容器】vector 和 list 的区别
    【C++百科】C++标准库到底是什么?
    【C++】设置、改变、获取系统环境变量:setenv & putenv & getenv
    【C++调试】error: 编译报错合集
    【C++调试】 warning: 编译警告合集
    Linux常用命令
    tcpdump及wireshark组合使用
    Vim快捷键
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7880719.html
Copyright © 2011-2022 走看看