复制&粘贴2

题目描述

文本编辑器的一个最重要的机能就是复制&粘贴。JOI社现在正在开发一款能够非常高速地进行复制&粘贴的文本编辑器,作为JOI社一名优秀的程序猿,你担负起了复制&粘贴功能的测试这一核心工作。整个JOI社的命运都系在你的身上,因此你无论如何都想写出一个正确且高速的程序来完成这项工作。
具体的做法如下所示。文件的内容是一个字符串S,对其进行N次复制&粘贴的操作,第i次操作复制位置Ai和位置Bi之间的所有文字,然后在位置Ci粘贴。这里位置x表示字符串的第x个字符的后面那个位置(位置0表示字符串的开头),例如字符串”copypaste”的位置6表示字符’a’和字符’s’之间的位置,位置9表示’e’后面的位置(即字符串的结尾)。不过,如果操作后的字符串长度超过了M,那么将超过的部分删除,只保留长度为M的前缀。
你的任务是写一个程序,输出N次操作后字符串的前K个字符。
1<=K<=200
1<=M<=10^9
S的每个字符都是小写字母(‘a’~’z’)
K<=|S|<=min(M,2*10^5)
1<=N<=2*10^5
设第i次操作前的字符串长度为Li,那么0<=Ai

直接搞

注意到k很小。
然后就是知道终止位置倒推它原来是在哪个位置。
分三类讨论,这题大水。
注意别作死递归。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
char s[maxn];
int a[maxn],b[maxn],c[maxn];
int i,j,k,l,t,n,m,len;
char get(int id,int k){
    if (!id) return s[k];
    if (k<=c[id]) return get(id-1,k);
    else if (k>c[id]&&k<=c[id]+b[id]-a[id]+1) return get(id-1,a[id]+k-c[id]-1);
    else return get(id-1,k-b[id]+a[id]-1);
}
int main(){
    freopen("copypaste.in","r",stdin);freopen("copypaste.out","w",stdout);
    scanf("%d%d",&m,&t);
    scanf("%s",s+1);
    scanf("%d",&n);
    fo(i,1,n) scanf("%d%d%d",&a[i],&b[i],&c[i]),a[i]++;
    fo(i,1,m) printf("%c",get(n,i));
}

你可能感兴趣的:(复制&粘贴2)