jzoj5249 【NOIP2017提高A組模擬8.10】文字編輯器 (序列修改類問題,資料結構)

jokerwyt發表於2017-08-10

題面

這裡寫圖片描述

這裡寫圖片描述

分析

splay的話是過不了最後一個點的。
顯而易見的我們可以考慮連結串列+tag,但是細節很多。
因為翻轉只翻轉兩個游標中間的地方,我們考慮將中間的放到一個佇列裡,然後左右兩邊分別開一個棧存。 (佇列左右兩邊各留下n的空位以供插入)
翻轉的話就調換一下佇列的head與tail,並且將正方向取反。
+正方向就相當於在序列上的後一個位置。
想一想,這樣設計的話別的操作不需要特殊考慮,和沒翻轉的情況一樣做就行。
還需要考慮l,r游標反過來的情況。但資料裡沒有所以沒打
怎麼考慮呢?
假如當l=r時l右移或r左移,我們就交換l,r游標,並標記錯位。這樣的話後面l左移就相當於r左移,與一般的情況是等價的。錯位的時候不能進行R操作。什麼時候l=r了就將錯位標記去掉。

兩個套起來想有點複雜,需要好好思考。

單獨維護游標區間,也是一些編輯器問題的套路。

Code

(不包括l,r錯位的情況)

#include <cstdio>
#include <iostream>
#include <cstring>
#define getf(x) ((x=='L')?0:1)
const int N=4*1e6+10;

using namespace std;
char s[N],op;
int tot,root,len;
int top0,top1,L,R,tag;
char q[N*4],S[2][N];
int n,f[2],dir;

void show() {
    for (int i=1; i<=top0; i++) putchar(S[0][i]);
    for (int i=L; i!=R; i+=dir) putchar(q[i]);
    putchar(q[R]);
    for (int i=top1; i; i--) putchar(S[1][i]);
    putchar('\n');
}
int readf() {char wf; scanf("%c",&wf); return getf(wf);}
int main() {
    freopen("33.in","r",stdin);
    freopen("33.out","w",stdout);
    scanf("%s\n%d",s+1,&n);
    int len=strlen(s+1);
    f[0]=0,f[1]=len;
    L=R=n+1; for (int i=1; i<=len; i++) q[R++]=s[i];
    --R; dir=1;
//  show();

    int w;
    for (int i=1; i<=n; i++) {
        scanf("\n%c ",&op);
        if (op!='R' && op!='S') w=readf();
        if (op=='>') {
            printf("%c\n",(f[w]==len)?'F':'T');
            if (f[w]<len) {
                ++f[w];
                if (w==0) S[0][++top0]=q[L],L+=dir;
                else q[R+=dir]=S[1][top1--];
            }
        } else
        if (op=='<') {
            printf("%c\n",(f[w]==0)?'F':'T');
            if (f[w]>0) {
                --f[w];
                if (w==0) q[L-=dir]=S[0][top0--];
                else S[1][++top1]=q[R],R-=dir;
            }
        } else
        if (op=='I') {
            char ne; scanf(" %c",&ne);
            if (w==0) S[0][++top0]=ne; else 
                q[R+=dir]=ne;
            printf("T\n");
            if (w==0) {
                if (f[1]>=f[0]) ++f[1];
                ++f[0]; 
            } else {
                if (f[0]>=f[1]) ++f[0];
                ++f[1];
            }
            ++len;
        } else 
        if (op=='D') {
            if (f[w]==len) {
                printf("F\n"); continue;
            } else printf("T\n");
            if (w==0) L+=dir; else 
                top1--;
            if (w==0) {
                if (f[1]>f[0]) --f[1];
            } else {
                if (f[0]>f[1]) --f[0];
            }
            --len;
        } else 
        if (op=='R') {
            if (tag) {
                printf("F\n"); continue;
            } else printf("T\n");
            swap(L,R); dir=-dir;
        } else 
        if (op=='S') show(),printf("\n");
//      printf("\n%d   ",i);
//      show();
//      printf("\n");
    }
}

相關文章