专栏文章
[CF2164D] Copy String 题解
CF2164D题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min0ttyn
- 此快照首次捕获于
- 2025/12/01 18:43 3 个月前
- 此快照最后确认于
- 2025/12/01 18:43 3 个月前
从右向左尝试让 匹配 中的一个字符。显然匹配到的 要先满足 。同时为了让已经放好的 不被其他字符覆盖, 这个区间不能被其他区间包含,即 。直接拿一个指针扫即可。于是得到 中每个字符最终的位置 。
对于每个 ,每次操作就将这个字符往右移动一格,直到移动到 。每次操作没有确定的部分就直接从前一次操作复制下来即可。
时间复杂度 。
注意这个实现并没有拿指针扫。
code
CPP#include<bits/stdc++.h>
#define pb emplace_back
#define pob pop_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const ll maxn=1000007,ee=1e18,p=998244353;
ll n,k,c,to[maxn];
string S,T,ans[maxn];
vector<ll> vec[26];
void chmax(ll &a,ll b){a=max(a,b);}
void solve(void){
for(ll i=0;i<26;i++) vec[i].clear();
for(ll i=1;i<=n;i++) to[i]=0,vec[S[i]-'a'].pb(i);
ll mx=n+1;
for(ll i=n,ch;i>=1;i--){
ch=T[i]-'a',mx=min(mx,i);
for(;!vec[ch].empty()&&vec[ch].back()>mx;) vec[ch].pob();
if(vec[ch].empty()) return cout<<"-1\n",void();
chmax(to[vec[ch].back()],i),mx=min(mx,vec[ch].back());
}
c=0;
for(ll i=1;i<=n;i++) c=max(c,to[i]-i);
if(c>k) return cout<<"-1\n",void();
if(c==0) return cout<<"0\n",void();
for(ll i=1;i<=c;i++) ans[i].clear(),ans[i].resize(n+1,'$');
for(ll i=n;i>=1;i--){
for(ll j=i+1;j<=i+c;j++){
ans[j-i][min(j,to[i])]=S[i];
}
}
ans[0]=S;
for(ll i=1;i<=c;i++){
for(ll j=1;j<=n;j++)if(ans[i][j]=='$') ans[i][j]=ans[i-1][j];
}
for(ll i=1;i<=n;i++)if(ans[c][i]!=T[i]) return cout<<"-1\n",void();
cout<<c<<"\n";
for(ll i=1;i<=c;i++) cout<<ans[i].substr(1,n)<<"\n";
}
int main(void){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
ll Tc=1; cin>>Tc;
for(;Tc--;){
cin>>n>>k>>S>>T,S=" "+S,T=" "+T;
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...