您的位置:首页 > 其它

Codeforces 176B Word Cut

2018-02-22 14:49 246 查看

Description

题面

题目大意:给定两个串A,B,每一次可以翻转A串的两个部分,如A=XY->YX,问恰好经过K次操作变成B串的方案数

Solution

需要注意到一个问题:本质不同的串最多只有 \(n-1\) 个

可以把A看成一个环,每一次翻转相当于改变一个起点

于是我们可以归类为两种串:1.原串 2.非原串

原串可以产生\(n-1\)个非原串,非原串可以产生 \(n-2\) 个非原串和 \(1\) 个原串

注意到:变成所有的非原串的方案数都是一样的

因为非原串中并不一定所有的都等于B,所以还需要枚举B等于哪几个非原串,判定加上几个非原串的贡献

设 \(f[i][0/1]\) 表示产生原串的方案数和产生非原串的方案数

\(f[i][0]=f[i-1][1]*(n-1)\)

\(f[i][1]=f[i-1][0]+(n-2)*f[i-1][1]\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,mod=1e9+7;
int ans=0,f
[2],K,n;char a
,b
;
inline bool check(int x){
for(int i=1;i<=n;i++){
if(a[x]!=b[i])return false;
x++;if(x==n+1)x=1;
}
return true;
}
int main(){
scanf("%s%s%d",a+1,b+1,&K);
n=strlen(a+1);
f[0][0]=1;
for(int i=1;i<=K;i++){
f[i][0]=1ll*f[i-1][1]*(n-1)%mod;
f[i][1]=(f[i-1][0]+1ll*f[i-1][1]*(n-2))%mod;
}
for(int i=1;i<=n;i++){
if(check(i)){
if(i==1)ans=(ans+f[K][0])%mod;
else ans=(ans+f[K][1])%mod;
}
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: