1. 程式人生 > >【題解】 bzoj1503: [NOI2004]郁悶的出納員 (Splay)

【題解】 bzoj1503: [NOI2004]郁悶的出納員 (Splay)

+= 地方 namespace 父親 noi down har str i++

bzoj1503,懶得復制,戳我戳我

Solution:

  • 我知不知道我是那根筋抽了突然來做splay,調了起碼\(3h+\),到第二天才改出來(我好菜啊),當做訓練調錯吧
  • 一個裸的splay,沒啥好說的

Attention:

  • 我的del操作裏面,註意連邊要把兒子的父親更改,父親的兒子更改,並且註意\(update\)

    void del(int x){
      ins(x);
      int now=root;
      if(ls(now))ans+=node[ls(now)].siz;
      if(node[now].cnt==1){connect(rs(now),0,1);update(root);}/////這個地方
    else {node[now].cnt--;node[now].ch[0]=0;node[ls(now)].fa=0;update(now);}////這個地方 return; }
  • 然後就是求rk時,先運行了一遍del,但是now存的root值是之前的,找了賊久才找到這個錯

之前的

int rk(int x){
  int now=root;del(low);

之後的

int rk(int x){
  del(low);int now=root;
  if(x>node[now].siz)return -1;
  while(1){
    pushdown(now);
    if(!now)return
-1; if(node[rs(now)].siz>=x){now=node[now].ch[1];} else if(node[rs(now)].siz+node[now].cnt>=x){Splay(now,root);return node[now].val;} else {x-=(node[rs(now)].siz+node[now].cnt);now=node[now].ch[0];} } }

Code:

//It is coded by Ning_Mew on 5.8
#include<bits/stdc++.h>
#define rs(x) node[x].ch[1]
#define ls(x) node[x].ch[0] #define fa(x) node[x].fa #define root node[0].ch[1] using namespace std; const int maxn=1e5+10007; int n,low,tot=0,ans=0; struct Node{ int fa,ch[2],val,cnt,siz,lazy; }node[maxn]; void update(int x){node[x].siz=node[ls(x)].siz+node[rs(x)].siz+node[x].cnt;} void connect(int x,int fa,int how){node[x].fa=fa;node[fa].ch[how]=x;} int ident(int x){return x==node[fa(x)].ch[0]?0:1;} void pushdown(int x){ if(node[x].lazy){ int lz=node[x].lazy;node[x].lazy=0; if(ls(x))node[ls(x)].val+=lz,node[ls(x)].lazy+=lz; if(rs(x))node[rs(x)].val+=lz,node[rs(x)].lazy+=lz;return; } } void rorate(int x){ int Y=fa(x),R=fa(Y);int Yson=ident(x),Rson=ident(Y); pushdown(Y);pushdown(x); connect(node[x].ch[Yson^1],Y,Yson); connect(Y,x,Yson^1); connect(x,R,Rson); update(Y);update(x); } void Splay(int x,int goal){ goal=fa(goal); while(fa(x)!=goal){ if(fa(fa(x))==goal)rorate(x); else if(ident(x)==ident(fa(x)))rorate(fa(x)),rorate(x); else rorate(x),rorate(x); }return; } int newnode(int x,int fa){node[++tot].val=x;node[tot].siz=node[tot].cnt=1;node[tot].fa=fa;return tot;} void ins(int x){ int now=root; if(!now){newnode(x,0);root=tot;return;} while(now){ node[now].siz++;pushdown(now); if(node[now].val==x){node[now].cnt++;Splay(now,root);/*root=now;*/return;} int nxt=x<node[now].val?0:1; if(!node[now].ch[nxt]){int pl=newnode(x,now);node[now].ch[nxt]=pl;Splay(pl,root);/*root=pl;*/return;} now=node[now].ch[nxt]; } } void pr(int now){ if(!now)return; cout<<"pr:"<<now<<‘ ‘<<node[now].siz<<‘ ‘<<node[now].val<<‘ ‘<<node[ls(now)].val<<‘ ‘<<node[rs(now)].val<<‘ ‘<<node[now].cnt<<endl; pr(ls(now));pr(rs(now));//update(now); } void del(int x){ ins(x); int now=root; if(ls(now))ans+=node[ls(now)].siz; if(node[now].cnt==1){ connect(rs(now),0,1);update(root); } else {node[now].cnt--;node[now].ch[0]=0;node[ls(now)].fa=0;update(now);} return; } int rk(int x){ del(low);int now=root; if(x>node[now].siz)return -1; while(1){ pushdown(now); if(!now)return -1; if(node[rs(now)].siz>=x){now=node[now].ch[1];} else if(node[rs(now)].siz+node[now].cnt>=x){Splay(now,root);return node[now].val;} else {x-=(node[rs(now)].siz+node[now].cnt);now=node[now].ch[0];} } } int main(){ scanf("%d%d",&n,&low); int x;char ch; for(int i=1;i<=n;i++){ cin>>ch;scanf("%d",&x); if(ch==‘I‘){if(x<low)continue;ins(x);} if(ch==‘A‘){node[root].val+=x;node[root].lazy+=x;} if(ch==‘S‘){node[root].val-=x;node[root].lazy-=x;del(low);} if(ch==‘F‘){printf("%d\n",rk(x));} } printf("%d\n",ans); return 0; }

【題解】 bzoj1503: [NOI2004]郁悶的出納員 (Splay)