【BZOJ1503】[NOI2004]郁闷的出纳员

来源:互联网 发布:淘宝滔搏运动城 真的吗 编辑:程序博客网 时间:2024/05/29 03:27

题意:整体加减+加点删点,查询第k大。

splay维护树即可。(话说第一次写splay,完全不会)

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <queue>#define N 100009#define ll long long#define inf 0x7fffffffusing namespace std;int n,Min,root,val[N],size[N],son[N][2],father[N],cnt=0,delta=0,ans=0;char ch;int x;void up(int x){    size[x]=size[son[x][0]]+size[son[x][1]]+1;}void rotate(int x){    int y=father[x],k=(son[y][0]==x);    son[y][!k]=son[x][k];    father[son[y][!k]]=y;    father[x]=father[y];    if (father[y]) son[father[y]][son[father[y]][1]==y]=x;    son[x][k]=y;    father[y]=x;    up(y);}void sy(int x,int g){    for (int y;(y=father[x])!=g;rotate(x))        if (father[y]) rotate((x==son[y][0])==(y==son[father[y]][0])?y:x);    up(x);    if (!g) root=x;}void newnode(int &x,int fa,int z){    x=++cnt;    father[x]=fa;    size[x]=1;    val[x]=z;    son[x][0]=son[x][1]=0;}void ins(int a){    if (!root)    {        root=++cnt;        val[root]=a;        size[root]=1;        return;    }    int x=root;    while (son[x][val[x]<a]) size[x]++,x=son[x][val[x]<a];    newnode(son[x][val[x]<a],x,a);    sy(son[x][val[x]<a],0);}int find(int x,int y){    if (y<=size[son[x][1]]) return find(son[x][1],y);    if (y==size[son[x][1]]+1) return val[x];    return find(son[x][0],y-size[son[x][1]]-1);}int dec(int &x,int fa){    if (!x) return 0;    int k;    if (val[x]+delta<Min)    {        k=dec(son[x][1],x)+size[son[x][0]]+1;        size[son[x][1]]=size[x]-k;        x=son[x][1];        father[x]=fa;    }    else    {        k=dec(son[x][0],x);        size[x]-=k;    }    return k;}int main(){    scanf("%d%d",&n,&Min);    root=0;    for (int i=1;i<=n;i++)    {        while (ch=getchar(),ch!='A'&&ch!='I'&&ch!='S'&&ch!='F');        scanf("%d",&x);        switch (ch)        {            case 'I':                if (x>=Min) ins(x-delta);                break;            case 'A':                delta+=x;                break;            case 'S':                delta-=x;                ans+=dec(root,0);                break;            case 'F':                printf("%d\n",x<=size[root]?find(root,x)+delta:-1);        }    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击