题目大意:
予你一字符串.于是便有了$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(' ');}