hdu4453 Looploop 2012年杭州现场赛 Splay

 

题意:维护一个圈,实现六个功能,给某位置起的一些数增加某值,反转某一段数,添加删除某些数,移动当前所指的位置,

简单的splay,把圈拆成链,对于每种操作,处理一下。

#define inf 0x3f3f3f3f
#define keyTree (ch[ ch[root][1] ][0])

const int maxn = 222222;

struct SplayTree {
  int sz[maxn];
  int ch[maxn][2];
  int pre[maxn];
  int root , top1 , top2;
  int ss[maxn] , que[maxn];

  void Rotate(int x,int f) {
    int y = pre[x];
    push_down(y);
    push_down(x);
    ch[y][!f] = ch[x][f];
    pre[ ch[x][f] ] = y;
    pre[x] = pre[y];
    if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] = x;
    ch[x][f] = y;
    pre[y] = x;
    push_up(y);
  }
  void Splay(int x,int goal) {
    push_down(x);
    //puts("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
    while(pre[x] != goal) {
      int y = pre[x], z = pre[y];
      push_down(z);
      push_down(y);
      push_down(x);
      if(pre[pre[x]] == goal) {
        Rotate(x , ch[pre[x]][0] == x);
      } else {
        int y = pre[x] , z = pre[y];
        int f = (ch[z][0] == y);
        if(ch[y][f] == x) {
          Rotate(x , !f) , Rotate(x , f);
        } else {
          Rotate(y , f) , Rotate(x , f);
        }
      }
    }
    push_up(x);
    if(goal == 0) root = x;
  }
  void RotateTo(int k,int goal) {//把第k位的数转到goal下边
    int x = root;
    push_down(x);
    while(sz[ ch[x][0] ] != k) {
      // printf("x = %d k = %d sz[x] = %d\n",x,k,sz[x]);
      if(k < sz[ ch[x][0] ]) {
        x = ch[x][0];
      } else {
        k -= (sz[ ch[x][0] ] + 1);
        x = ch[x][1];
      }
      push_down(x);
    }
    Splay(x,goal);
  }

  //以上一般不修改//////////////////////////////////////////////////////////////////////////////
  void debug() {
    printf("%d\n",root);
    Treaval(root);
  }
  void Treaval(int x) {
    push_down(x);
    if(x) {
      Treaval(ch[x][0]);
      printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
      Treaval(ch[x][1]);
    }
  }
  //以上Debug
  //以下是题目的特定函数:
  void NewNode(int &x,int c) {
    x = ++top1;
    ch[x][0] = ch[x][1] = pre[x] = 0;
    sz[x] = 1;
    val[x] = c;
    lazy[x] = add[x] = 0 ;
  }
  //把延迟标记推到孩子
  void push_down(int x) {
    if(lazy[x] != 0 )
    {
      rev(ch[x][0]);
      rev(ch[x][1]);
      //swap(add[ch[x][0]],add[ch[x][1]]);
      lazy[x] = 0 ;
    }
    if(add[x] != 0 )
    {
      val[ch[x][0]] += add[x];
      val[ch[x][1]] += add[x];
      add[ch[x][0]] += add[x];
      add[ch[x][1]] += add[x];
      add[x] = 0 ;
    }
    return ;
  }
  //把孩子状态更新上来
  void push_up(int x) {
    sz[x] = 1 + sz[ ch[x][0] ] + sz[ ch[x][1] ];
  }
  /*初始化*/
  void makeTree(int &x,int l,int r,int f) {
    if(l > r) return ;
    int m = (l + r)>>1;
    NewNode(x , num[m]);        /*num[m]权值改成题目所需的*/
    makeTree(ch[x][0] , l , m - 1 , x);
    makeTree(ch[x][1] , m + 1 , r , x);
    pre[x] = f;
    push_up(x);
  }
  void clear() {
    cnt = 0 ;
    ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
    add[0] = lazy[0] = 0 ;
    root = top1 = 0;
    //为了方便处理边界,加两个边界顶点
    NewNode(root , -inf);
    NewNode(ch[root][1] , inf);
    pre[top1] = root;
    sz[root] = 2;
  }
  void init(int pos,int n) {
    clear();
    cnt =  n;
    RotateTo(pos , 0 );
    RotateTo(pos + 1, root);
    makeTree(keyTree , 1 , n   , ch[root][1]);
    push_up(ch[root][1]);
    push_up(root);
  }
  void update(int u,int v,int _add )
  {
    RotateTo(u - 1 , 0 );
    RotateTo(v + 1, root );
    add[keyTree] += _add;
    val[keyTree] += _add;
    push_up(root);
    //Splay(keyTree,root);
  }
  void rev(int x)
  {
    if(x == 0 ) return;
    swap(ch[x][0] ,ch[x][1]);
    lazy[x] ^= 1;
  }
  void lz(int u,int v )
  {
    RotateTo(u - 1 , 0 );
    RotateTo(v + 1 , root );
    rev(keyTree);
    //Splay(keyTree,root);
  }
  int split(int u,int v )
  {
    RotateTo(u - 1 , 0 );
    RotateTo(v + 1 , root );
    int res = keyTree;
    keyTree = 0 ;
    push_up(ch[root][1]);
    push_up(root);
    return res ;
  }
  void hb(int k,int ts)
  {
    RotateTo(k - 1 ,0 );
    RotateTo(k , root);
    keyTree = ts ;
    pre[ts] = ch[root][1];
    push_up(ch[root][1]);
    push_up(root);
  }
  void insert(int k,int val)
  {
    cnt ++ ;
    RotateTo(k - 1 , 0 );
    RotateTo(k , root ) ;
    NewNode(keyTree,val);
    pre[keyTree] = ch[root][1];
    push_up(ch[root][1]);
    push_up(root);
  }
  int getkth(int k )
  {
    int x = root ;
    push_down(x);
    while(sz[ ch[x][0] ] != k) {
      // printf("x = %d k = %d sz[x] = %d\n",x,k,sz[x]);
      if(k < sz[ ch[x][0] ]) {
        x = ch[x][0];
      } else {
        k -= (sz[ ch[x][0] ] + 1);
        x = ch[x][1];
      }
      push_down(x);
    }
    return val[x];
  }
  void del(int k) {
    RotateTo(k - 1 , 0);
    RotateTo(k + 1 , root);
    //printf("val = %d\n",val[keyTree]);
    //printf("sz = %d\n",sz[keyTree]);
    cnt -- ;
    keyTree = 0 ;
    push_up(ch[root][1]);
    push_up(root);
    // erase(keyTree);
  }
  int cnt ;
  /*这是题目特定变量*/
  int num[maxn];
  int val[maxn];
  int add[maxn];
  int lazy[maxn];

} spt;

int n,m,k1,k2;
int wh;
int main()
{
  int cas;
  cas = 0 ;
  char str[10];
  while(
        scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF && !(n == 0 && m == 0 && k1 == 0 && k2 == 0 ) )
  {
    for(int i =1 ; i<= n ; i ++ ) scanf("%d",&spt.num[i]);
    spt.init(0,n);
    wh =  1 ;
    printf("Case #%d:\n",++cas);
    int x;
    while(m -- )
    {
      scanf("%s",str);
      if( str[0] == 'q' )
      {
        int ans = spt.getkth(wh);
        printf("%d\n",ans);
      }
      else if( str[0] == 'r' )
      {
        if(wh + k1 - 1 <= spt.cnt)
        {
          spt.lz(wh , wh + k1 - 1);
        }
        else
        {
          int p1,p2,p3,p4;
          p4 = spt.cnt;
          p1 = wh + k1 - 1 - spt.cnt;
          p2 = spt.split(1,p1);
          wh = wh - p1;
          p4 = p4 - p1;
          spt.hb(p4 + 1 ,p2);
          p1 = wh + k1 - 1 ;
          spt.lz(wh,p1);
        }
      }
      else if(str[0] == 'i')
      {
        scanf("%d",&x);
        spt.insert(wh + 1 ,x);
      }
      else if(str[0] == 'm')
      {
        scanf("%d",&x);
        if(x == 1 )
        {
          wh -- ;
          if(wh == 0 ) wh = spt.cnt;
        }
        else
        {
          wh ++ ;
          if(wh >spt.cnt) wh = 1;
        }
      }
      else if(str[0] == 'd')
      {
        if(wh == spt.cnt)
        {
          spt.del(wh);
          wh = 1;
        }
        else
        {
          spt.del(wh);
        }
      }
      else if(str[0] == 'a')
      {
        scanf("%d",&x);
        int p1,p2,p3,lef;
        if(wh + k2 - 1 <= spt.cnt)
        {
          spt.update(wh,wh + k2 - 1 ,x);
        }
        else
        {
          lef  = wh + k2 - 1 - spt.cnt;
         // printf("%d %d \n",k2,lef);
          spt.update(1,lef,x);
          spt.update(wh,spt.cnt,x);
        }
      }
     // spt.debug();
    }
  }
  return 0;
}
View Code

7k+的代码,居然调出来了,好开心。

posted on 2013-08-23 20:30  oshixiaoxiliu  阅读(309)  评论(0编辑  收藏  举报

导航