[20200728NOIP提高组模拟T1]Copy

题目大意:

  予你一字符串.于是便有了$n$次操作,每次操作给你三个变量$a,b,c$,将$(a,b]$处字符插入$(c,c+b-a]$处,原序列右移.此后便有了查询,请你输出操作后$[1,k]$位字符.

solution:

  考虑k比较小,所以我们可以进行dp,从后往前推,一一枚举$[1,k]$操作前的位置即可.设$pos[i]$表示最后$i$处字符的位置,那么有以下三种情况:一、若$pos[i]<=c$,那无需转移;二、若$pos[i] in (c,c+b-a]$,那么向$(a,b]$处原位置转移;三、若$pos[i] > c+b-a$,那么向前平移即可.

code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define R register
#define next kdjadskfj
#define debug pust("mlg")
using namespace std;
typedef int ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
inline void writesp(ll x);
ll k,m,n;
ll pos[250];
char wn[1010000];
ll h;
ll a[1010000],b[1010000],c[1010000];
int main(){
    freopen("copypaste.in","r",stdin);
    freopen("copypaste.out","w",stdout);
    k=read();m=read();
    char C=getchar();
    while(C<'a'||C>'z') C=getchar();
    while(C>='a'&&C<='z') wn[++h]=C,C=getchar();
    n=read();
    for(R ll i=1;i<=k;i++) pos[i]=i;
    for(R ll i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read();
    for(;n;n--){
        for(R ll i=1;i<=k;i++){
            if(pos[i]<=c[n]) continue;
            if(pos[i]>c[n]+b[n]-a[n]){pos[i]-=(b[n]-a[n]);continue;}
            pos[i]=a[n]+pos[i]-c[n];
        }
    }
    for(R ll i=1;i<=k;i++) putchar(wn[pos[i]]);
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('
');}
原文地址:https://www.cnblogs.com/ylwtsq/p/13391620.html