题解 [AGC033E] Go around a Circle
设给定字符串为
不妨设
此时
考虑策略会是怎样的,设初始放棋子的位置左侧有
除此之外,发现我们每次走完
注意此时我们有一点需要特殊判断,即当
而对于非全
本题再次启发我们在无从下手时,要仔细分析题目性质,通过增加限制减少决策的方式,解决转化后的问题。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int mod=1e9+7;
int n,m;
char s[N];
ll dp[N],sum[N],f[N][2];
bool flag1,flag2;
int read(){
int w=0,fh=1;
char c=getchar();
while (c>'9'||c<'0'){
if (c=='-') fh=-1;
c=getchar();
}
while (c>='0'&&c<='9'){
w=(w<<3)+(w<<1)+(c^48);
c=getchar();
}
return w*fh;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=read(),m=read();
scanf("%s",s+1);
if (s[1]=='B'){
for (int i=1;i<=m;i++)
s[i]=(s[i]=='B')?'R':'B';
}
int minn=1e9;
for (int i=1,len=0,hav=1;i<=m;i++){
if (s[i]=='B'){
if (len&1||hav) minn=min(minn,len);
len=0,hav=0;
}else ++len;
if (s[i]=='B') flag1=1;
else if (s[i]=='R') flag2=1;
}
if (!flag1||!flag2){
ll ans=0;
f[1][0]=1;
for (int i=2;i<=n;i++)
f[i][0]=(f[i-1][0]+f[i-1][1])%mod,f[i][1]=f[i-1][0];
ans=(f[n][0]+f[n][1])%mod;
f[1][0]=0,f[1][1]=1;
for (int i=2;i<=n;i++)
f[i][0]=(f[i-1][0]+f[i-1][1])%mod,f[i][1]=f[i-1][0];
ans=(ans+f[n][0])%mod;
cout<<ans<<"\n";
return 0;
}
if (n&1){
puts("0");
return 0;
}
n/=2,minn=minn/2+1;
for (int i=1;i<=minn;i++) dp[i]=2*i;
for (int i=1;i<=n;i++){
dp[i]=(dp[i]+sum[i-1])%mod;
if (i-minn-1>=0) dp[i]=(dp[i]-sum[i-minn-1]+mod)%mod;
sum[i]=(sum[i-1]+dp[i])%mod;
// cout<<dp[i]<<"\n";
}
cout<<dp[n]<<"\n";
return 0;
}