您的位置:首页 > 理论基础 > 数据结构算法

NOI2004郁闷的出纳员bzoj3503

2015-08-22 23:44 661 查看
题目大意是给出一些操作,支持删除插入查找一些值,就是动态维护一些值。

分析:不想写splay感觉有点难写虽然听WQS说splay好处多多,所以同treap来了一发,删除的时候发现当前节点不行就直接删除左子树全部就行啦,没有单点删除感觉还是萌萌哒很快就能写出来哒,树内放的是与基准值delta的差值哦

恶补数据结构第一站treap。#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define N 100005
using namespace std;
int ra
,ls
,rs
,root,siz
,key
;
int n,m,delta,ans,len;

void push(int k)
{
siz[k]=siz[ls[k]]+siz[rs[k]]+1;
}

void rturn(int &k)
{
int t=ls[k];
ls[k]=rs[t];
rs[t]=k;
siz[t]=siz[k];
push(k);
k=t;
}

void lturn(int &k)
{
int t=rs[k];
rs[k]=ls[t];
ls[t]=k;
siz[t]=siz[k];
push(k);
k=t;
}

void ins(int &k,int val)
{
if (k==0)
{
k=++len;
ra[k]=rand();
key[k]=val;
siz[k]=1;
return;
}
siz[k]++;
if (val<key[k])
{
ins(ls[k],val);
if (ra[k]>ra[ls[k]]) rturn(k);
}
else
{
ins(rs[k],val);
if (ra[k]>ra[rs[k]]) lturn(k);
}
}

int del(int &k,int x)
{
if (!k) return 0;
int t;
if (x>key[k])
{
t=siz[ls[k]]+1;
k=rs[k];
return t+del(k,x);
}
else
{
t=del(ls[k],x);
siz[k]-=t;
return t;
}
}

int findd(int k,int x)
{
if (siz[ls[k]]+1==x) return key[k];
if (siz[ls[k]]+1<x) return findd(rs[k],x-siz[ls[k]]-1);
else return findd(ls[k],x);
}

int main()
{
char op[1];int x;
scanf("%d%d",&n,&m);
while (n--)
{
scanf("%s%d",op,&x);
if (op[0]=='I') if (x>=m) ins(root,x-delta);
if (op[0]=='A') delta+=x;
if (op[0]=='S') {delta-=x;ans+=del(root,m-delta);}
if (op[0]=='F')
{
if (x>siz[root]) printf("-1\n");
else printf("%d\n",findd(root,siz[root]-x+1)+delta);
}
}printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息