T1 郁闷的出纳员

一个数据结构,支持单点插入、删除几个不一定连续的点、查询k值操作

初做:2017.2.18   time:1268ms    memory:3MB

http://www.cnblogs.com/TheRoadToTheGold/p/6412790.html

现在:2017.3.28   time:570ms   memory:3MB

初做时直接套模板,删除分5种情况,

本题实际只需3种情况

这一次的查询用递归写的

int query(int now,int k)
{
	int tmp=0;
	if(ch[now][0]) tmp=sum[ch[now][0]];
	if(k<=tmp) return query(ch[now][0],k);
	if(tmp+cnt[now]>=k) return key[now];
	return query(ch[now][1],k-tmp-cnt[now]);
}

5行开始写的时候每一行都有错误

第二行:tmp=左子树节点个数,遗漏了判断是否有左子树

第三行:当k<=左子树节点个数,漏了等于号

第四行:左子树节点个数+根节点个数(cnt[]数组)>=k,cnt[]和sum[]混了,>写的<

第五行:cnt和sum混了

 

再就是splay写丑了

贴个精简的:

inline void splay(int x)
{
    for(int fa;fa=f[x];rotate(x))
      if(f[fa]) rotate(getson(x)==getson(fa) ? fa:x);
    root=x;
    update(x);
}

 

一定要注意update时节点是否有左右孩子

 

rotate里出现了一个错误:

if(z) ch[z][ch[z][1]==y]=x;

fa[x]=z;这一句是不在if(z)里的

#include<cstdio>
#define N 100001
using namespace std;
int n,limit,gather,root,tot,leave;
int sum[N],ch[N][2],fa[N],key[N],cnt[N];
void newroot(int x)
{
    sum[++tot]=cnt[tot]=1;
    key[tot]=x;
    root=tot;
}
void newnode(int f,int x)
{
    sum[++tot]=cnt[tot]=1;
    key[tot]=x;
    fa[tot]=f;
    ch[f][x>key[f]]=tot;
}
void update(int x)
{
    sum[x]=cnt[x];
    if(ch[x][0]) sum[x]+=sum[ch[x][0]];
    if(ch[x][1]) sum[x]+=sum[ch[x][1]];
}
void rotate(int x,int kind)
{
    int y=fa[x],z=fa[y];
    ch[y][!kind]=ch[x][kind]; fa[ch[y][!kind]]=y;
    ch[x][kind]=y;fa[y]=x;
    fa[x]=z;
    if(z) ch[z][ch[z][1]==y]=x;
    update(y);
}
void splay(int x)
{
    while(fa[x])
    {
        int y=fa[x],kind=ch[y][1]==x;
        if(!fa[y]) rotate(x,!kind);
        else
        {
            int z=ch[fa[y]][1]==y;
            if(z==kind) 
            {
                rotate(y,!kind);
                rotate(x,!kind);
            }
            else
            {
                rotate(x,!kind);
                rotate(x,kind);
            }
        }
    }
    update(x);
    root=x;
}
void insert(int x)
{
    if(!root) 
    {
        newroot(x);
        return;
    }
    int now=root;
    while(ch[now][x>key[now]])
    {
        if(key[now]==x)
        {
            cnt[now]++;
            update(now);
            splay(now);
            return;
        }
        now=ch[now][x>key[now]];
    }
    if(key[now]==x)
    {
        cnt[now]++;
        update(now);
        splay(now);
        return;
    }
    newnode(now,x);
    update(now);
    splay(tot);
}
void cut_lch()
{
    int tmp=ch[root][0];
    if(tmp) leave+=sum[tmp];
    fa[tmp]=0; ch[root][0]=0;
    update(root);
}
void cut()
{
    if(cnt[root]>1)
    {
        cnt[root]--;
        update(root);
        return;
    }
    if(!ch[root][1])
    {
        root=0;
        gather=0;
        return;
    }
    int tmp=ch[root][1];
    fa[tmp]=0;
    ch[root][1]=0;
    root=tmp;
}
int query(int now,int k)
{
    int tmp=0;
    if(ch[now][0]) tmp=sum[ch[now][0]];
    if(k<=tmp) return query(ch[now][0],k);
    if(tmp+cnt[now]>=k) return key[now];
    return query(ch[now][1],k-tmp-cnt[now]);
}
int main()
{
    freopen("cashier.in","r",stdin);
    freopen("cashier.out","w",stdout);
    scanf("%d%d",&n,&limit);
    char ch[1];int x;
    while(n--)
    {
        scanf("%s%d",ch,&x);
        switch(ch[0])
        {
            case 'I':
                if(x<limit) continue;
                insert(x-gather); break;
            case 'A':
                gather+=x; break;
            case 'S':
                gather-=x;
                insert(limit-gather);
                cut_lch();
                cut();
                break;
            case 'F':
                if(x>sum[root]) printf("-1\n");
                else printf("%d\n",query(root,sum[root]-x+1)+gather);
        }
    }
    printf("%d",leave);
}
View Code

相关文章:

  • 2021-07-22
  • 2021-09-28
  • 2021-05-24
  • 2021-08-12
  • 2021-06-26
猜你喜欢
  • 2021-07-10
  • 2021-09-01
相关资源
相似解决方案