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


    题目大意:
    一个计算机支持一下三中操作:
    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.
  • 相关阅读:
    前端之CSS盒模型介绍
    前端之CSS列表及背景类属性
    前端之CSS字体和文本类属性
    流程控制语句
    前端之CSS语法及选择器
    前端之CSS创建的样式
    前端之HTML语法及常用标签
    前端之HTML样式
    网页制作之前端简介
    jQuery(一)、核心
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313035.html
Copyright © 2020-2023  润新知