• hdu4699 Editor 2013 多校训练第十场 D题 数列维护 splay | 线段树 | 栈!!!!!


    题意:维护一个文本编辑,并且查询最大前缀和。

    写了splay,wa了13次

    过了之后觉着特傻逼。发现题解两个栈就可以了,光标前后维护两个栈,维护前面的栈的前缀和 和 最大前缀和。

    哎,傻逼,太弱了,还是没仔细分析题目的特殊性质。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <cassert>
    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <map>
    #include <set>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <iomanip>
    using namespace std;
    
    #define abs(x) ((x)>=0?(x):-(x))
    #define i64 long long
    #define u32 unsigned int
    #define u64 unsigned long long
    #define clr(x,y) memset(x,y,sizeof(x))
    #define PI acos(-1.0)
    #define sqr(x) ((x)*(x))
    
    
    #define inf 0x3f3f3f3f
    #define keyTree (ch[ ch[root][1] ][0])
    
    const int maxn = 2222222;
    
    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];
        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) {
        while(pre[x] != goal) {
          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;
        while(sz[ ch[x][0] ] != k) {
          // printf("x = %d k = %d sz[x] = %d
    ",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];
          }
        }
        Splay(x,goal);
      }
    
    
      //以上一般不修改//////////////////////////////////////////////////////////////////////////////
      void debug() {
        printf("%d
    ",root);
        Treaval(root);
      }
      void Treaval(int x) {
        if(x) {
          Treaval(ch[x][0]);
          printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d
    ",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;
        sum[x] = c;
        pf[x] = c;
      }
      //把孩子状态更新上来
      void push_up(int x) {
        sz[x] = 1 + sz[ ch[x][0] ] + sz[ ch[x][1] ];
        sum[x] = val[x] + sum[ch[x][0]] + sum[ch[x][1]];
    
        pf[x] = max(pf[ch[x][0]] , sum[ch[x][0]] + val[x] + pf[ch[x][1]] );
        pf[x] = max(pf[x] , sum[ch[x][0]] + val[x]);
    
        return ;
      }
      /*初始化*/
      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;
        val[0] =  sum[0] = 0 ;
        pf[0] = -inf;
        root = top1 = 0;
        //为了方便处理边界,加两个边界顶点
        NewNode(root , -inf);
        NewNode(ch[root][1] , 0);
        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 insert(int k , int value) {
        cnt ++ ;
        RotateTo(k - 1 , 0);
        RotateTo(k , root);
        NewNode(keyTree,value);
        pre[keyTree] = ch[root][1];
        push_up(root);
      }
      void del(int k) {
        RotateTo(k - 1 , 0);
        RotateTo(k + 1 , root);
        //printf("val = %d
    ",val[keyTree]);
        //printf("sz = %d
    ",sz[keyTree]);
        cnt -- ;
        keyTree = 0 ;
        push_up(root);
        // erase(keyTree);
      }
      int query(int k)
      {
        if(k > cnt) k = cnt;
        RotateTo(0,0);
        RotateTo(k + 1 ,root);
        //printf("sz = %d
    ",sz[keyTree]);
        return pf[keyTree];
      }
      int cnt ;
      /*这是题目特定变量*/
      int val[maxn];
      int sum[maxn];
      int pf[maxn];
    } spt;
    
    int main()
    {
      char str[5];
      int Q;
      while(scanf("%d",&Q)!=EOF)
      {
        spt.init(0,0);
        int loc;
        int x;
        loc = 0 ;
        while(Q -- )
        {
          scanf("%s",str);
          if(str[0] == 'I')
          {
            scanf("%d",&x);
            spt.insert(loc + 1 ,x);
            loc ++ ;
          }
          else if(str[0] == 'Q')
          {
            scanf("%d",&x);
            if(x > loc ) x = loc ;
            int ans = spt.query(x);
            printf("%d
    ",ans);
          }
          else if(str[0] == 'L')
          {
            if(loc > 0 )
              loc -- ;
          }
          else if(str[0] == 'R')
          {
            if(loc < spt.cnt)
              loc ++ ;
          }
          else if(str[0] == 'D')
          {
            spt.del(loc);
            loc -- ;
          }
         // spt.debug();
        }
      }
      return 0;
    }
    代码不忍直视

    以后补上维护栈的代码

  • 相关阅读:
    数论-剩余类、完全剩余系、缩系、欧拉函数
    数论-同余式
    计算机科研项目中的重点项目、重大项目、重大研究计划项目,重点研发计划有什么区别和联系?
    VFS虚拟文件系统
    git中文名转义带来的麻烦;git配置之core.quotepath;git中文乱码
    nodejs 与 npm 配置
    mongodb 部署 安装 使用 记录
    GPG error: https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 656408E390CFB1F5
    slurm 网路监控软件使用
    Win10 64位,北航研究生教务系统文件打印办法(旧版GSMIS),只要三步就能解决;
  • 原文地址:https://www.cnblogs.com/jh818012/p/3275356.html
Copyright © 2020-2023  润新知