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); 
}
原文地址:https://www.cnblogs.com/xuanyiming/p/7880719.html