【JZOJ 5249】【NOIP2017提高A组模拟8.10】文本编辑器

Description

这里写图片描述

Solution

这道题用Splay是一道版子题,
但很遗憾,只有90分,
那O(n)怎么做呢?

我们发现,对于全局的数,可以用2个栈,1个队列表示:
设两个光标位置为l,r,
两个栈分别表示l前面的数、r后面的数,队列表示l~r中间的数,
那么对于简单的移动操作,直接做即可,
对于翻转,我们发现,直接打上标记即可,在光标移动的时候判断一下即可,
当然还有特殊情况:当r在l左边(注意题目对左右光标的定义),这样就有问题,
我们发现,对于这种情况,把l,r互换,这样除了不能翻转以外, 操作与正常情况相比没有区别,
那么就打上两个标记即可,代码嘛….真有点恶心啊QwQ~

复杂度 O(n)

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
#define SD(q) ((q)==b[b[q].fa].r)
using namespace std;
const int N=8000500;
int read(int &n)
{
    char ch=' ';int q=0,w=1;
    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
    if(ch=='-')w=-1,ch=getchar();
    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans,alln;
int dh[N],dt[N];
int d[N*2];
bool RT,OK;
int main()
{
    int q,w,_;char ch;
    int S=N,T=N-1;
    for(ch=getchar();ch<=126&&ch>=33;ch=getchar())d[++T]=ch;
    read(_);
    fo(II,1,_)
    {
        for(ch=' ';ch!='I'&&ch!='>'&&ch!='<'&&ch!='D'&&ch!='R'&&ch!='S';ch=getchar());
        char k=ch;
        if(ch=='S')
        {
            fo(i,1,dh[0])putchar(dh[i]);
            if(RT)fod(i,T,S)putchar(d[i]);
            else fo(i,S,T)putchar(d[i]);
            fod(i,dt[0],1)putchar(dt[i]);
            putchar('\n');
            continue;
        }
        if(ch=='R')
        {
            if(!OK&&S<=T)RT=!RT,putchar('T'),putchar('\n');
            else putchar('F'),putchar('\n'),RT=0;
            continue;
        }
        for(ch=' ';ch!='L'&&ch!='R';ch=getchar());
        if(OK){if(ch=='L')ch='R';else ch='L';}
        if(k=='<')
        {
            if(ch=='L')
            {
                if(dh[0])
                {
                    if(RT)d[++T]=dh[dh[0]--];
                        else d[--S]=dh[dh[0]--];
                    putchar('T'),putchar('\n');
                }
                else putchar('F'),putchar('\n');
            }else
            {
                if(S<=T)
                {
                    if(RT)dt[++dt[0]]=d[S++];
                        else dt[++dt[0]]=d[T--];
                    putchar('T'),putchar('\n');
                }
                else
                { 
                    if(dh[0])
                    {
                        putchar('T'),putchar('\n');
                        OK=!OK;RT=0;
                        d[--S]=dh[dh[0]--];
                    }else putchar('F'),putchar('\n');
                }
            }
        }else if(k=='>')
        {
            if(ch=='R')
            {
                if(dt[0])
                {
                    if(RT)d[--S]=dt[dt[0]--];
                        else d[++T]=dt[dt[0]--];
                    putchar('T'),putchar('\n');
                }
                else putchar('F'),putchar('\n');
            }else
            {
                if(S<=T)
                {
                    if(RT)dh[++dh[0]]=d[T--];
                        else dh[++dh[0]]=d[S++];
                    putchar('T'),putchar('\n');
                }
                else 
                {
                    if(dt[0])
                    {
                        putchar('T'),putchar('\n');
                        OK=!OK;RT=0;
                        d[++T]=dt[dt[0]--];
                    }else putchar('F'),putchar('\n');
                }
            }
        }else if(k=='I')
        {
            putchar('T'),putchar('\n');
            char ch1=ch;
            for(ch=getchar();ch>126||ch<33;ch=getchar());
            if(ch1=='R')
            {
                if(RT)d[--S]=ch;
                    else d[++T]=ch;
            }else dh[++dh[0]]=ch;
        }else
        {
            if(ch=='L')
            {
                if(S>T)
                {
                    if(!dt[0])putchar('F'),putchar('\n');
                    putchar('T'),putchar('\n');
                    dt[0]--;
                }
                else {if(RT)T--;else S++;putchar('T'),putchar('\n');}
            }else
            {
                if(!dt[0]){putchar('F'),putchar('\n');continue;}
                dt[0]--;putchar('T'),putchar('\n');
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值