• 高级打字机【主席树】【滚动数组】【块状链表】


    题目大意:
    一个计算机支持一下三中操作:
    TT xx:在文章末尾打下一个小写字母xx
    UU xx:撤销最后的xx次修改操作。
    QQ xx:询问当前文章中第xx个字母并输出。
    InputInput

    7
    T a
    T b
    T c
    Q 2
    U 2
    T c
    Q 2

    OutputOutput

    b
    c

    思路:
    IOI题目。。。
    正解是主席树(当然啦什么TrieTrie+倍增法寻祖,可持久化跳表,可持久化块状数组无敌的东西都可以做)。
    但是本蒟蒻是用滚动数组水过了这道题。


    本题有三个阶段:

    1. 对于5050%的数据 n100000n≤100000;保证UU操作不会撤销UU操作.
    2. 对于100100%的数据 n100000n≤100000UU操作可以撤销UU操作。
    3. IOIIOI挑战:必须使用在线算法完成该题。

    阶段33就直接放弃了 毕竟我还不会主席树
    那么对于阶段11,我们只要模拟堆,就可以很简单地得到这部分分。

    var
      tail,n,i,j,x:longint;
      c:array[1..100000] of char;  //模拟堆
      ch,orz:char;
    begin
      readln(n);
      for i:=1 to n do
       begin
         read(ch,orz);
         if ch='T' then  //插入
          begin
            inc(tail);  
            readln(c[tail]);  //放入堆顶
          end;
         if ch='Q' then  //询问
          begin
            readln(x);
            writeln(c[x]);  //输出第i位
          end;
         if ch='U' then  //删除
          begin
            readln(x);
            dec(tail,x)  //将最后x位输出
          end;
       end;
    end.

    对于阶段二,我们也要把它分为两部分。
    我们可以开一个长度为100000100000ansistringansistring数组sss[i]s[i]表示第ii种情况。再开一个sumsum,表示第几种情况。这样,当我们遇到UU操作时,把前面xx个操作还原,其实就是不做前xx个操作,直接赋值为s[sum-x-1]。这样可以得到90分。
    这里写图片描述

    var
      sum,n,i,j,x:longint;
      s:array[1..100000] of ansistring;
      ch,orz:char;
    begin
      readln(n);
      for i:=1 to n do
       begin
         read(ch,orz);
         if ch='T' then
          begin
            readln(ch);
            inc(sum);
            s[sum]:=s[sum-1]+ch;  //储存情况
          end;
         if ch='Q' then
          begin
            readln(x);
            writeln(s[sum][x]);  //输出现在的情况的第x位
          end;
         if ch='U' then
          begin
            readln(x);
            inc(sum);  //也算一种情况
            s[sum]:=s[sum-1-x];  //直接取第sum-1-x位
          end;
       end;
    end.

    但是这样会MLE,ss数组开的太大了。所以我们要用滚动数组来优化。每次将sumsum%2000020000就可以了。


    代码:

    const 
      k=20000;  //滚动数组,其他与90分代码一样。
    var
      sum,n,i,j,x:longint;
      s:array[1..k] of ansistring;
      ch,orz:char;
    begin
      readln(n);
      for i:=1 to n do
       begin
         read(ch,orz);
         if ch='T' then
          begin
            readln(ch);
            inc(sum);
            s[sum mod k]:=s[(sum-1)mod k]+ch;
          end;
         if ch='Q' then
          begin
            readln(x);
            writeln(s[sum mod k][x]);
          end;
         if ch='U' then
          begin
            readln(x);
            inc(sum);
            s[sum mod k]:=s[(sum-1-x) mod k];
          end;
       end;
    end.
  • 相关阅读:
    七月随想
    曾经的诗
    Foundry feats. MultiverseStudio
    "BLAME" is out.
    去除partner页面消息 自动添加关注者的功能
    Odoo小数精度及货币精度详解
    CentOs 6.x 升级 Python 版本【转】
    django template if return false
    Odoo “坑” 系列之 XML中的布尔类型
    Qweb报表中的Reload from Attachment参数
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313035.html
Copyright © 2020-2023  润新知