2539 最优填充2
字符串ss只包含两种字符A,BA,B,已知它某些位上的字符,你想要把它填
充完整使得相同字母相邻的情况尽量少,问有多少种最优填充方案。答案对1e9+7取模。
输入
第一行两个数n,m,表示字符串长度,已知位置数。 第二行m个数pos[i]; 第三行一个长度为m的字符串val[i],表示s[pos[i]]=val[i]。 保证pos[i]两两不同。 n<=10^9,m<=50,1<=pos[i]<=n,val[i]='A'or'B'。输出
一个数,表示最优方案数,答案对1e9+7取模。输入样例
3 2 1 3 25 15 23 4 8 1 24 9 16 17 6 2 25 15 14 7 13 ABBBBABABBAAABA 305 28 183 115 250 1 188 193 163 221 144 191 92 192 58 215 157 187 227 177 206 15 272 232 49 11 178 59 189 246 ABAABBABBAABABBBBAAAABBABBBA输出样例
2 1 43068480
思路:
之前做过构造这种序列,思路很清晰,这题唯一注意的话就是
两位置之间一定有字母相同,那方案数不是乘以2,应该是乘以区间
内数字数目减一。详见代码。
代码实现:
#include<iostream>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=6e3+100;
const int mod=1e9+7;
struct Node {
int pos;
char val;
} arr[N];
bool cmp(Node aa,Node bb) {
return aa.pos<bb.pos;
}
int main() {
#ifdef MYHOME
freopen("input.txt","r",stdin);
#endif
int n,m,ans;
while(cin>>n>>m) {
ans=1;
for(int i=1; i<=m; i++) {
cin>>arr[i].pos;
}
for(int i=1; i<=m; i++) {
cin>>arr[i].val;
}
sort(arr+1,arr+1+m,cmp);
for(int i=2; i<=m; i++) {
if(((arr[i].pos-arr[i-1].pos)%2==0)&&arr[i].val!=arr[i-1].val) {
ans=((LL)ans*(LL)(arr[i].pos-arr[i-1].pos))%mod;
} else if(((arr[i].pos-arr[i-1].pos)%2==1)&&arr[i].val==arr[i-1].val) {
ans=((LL)ans*(LL)(arr[i].pos-arr[i-1].pos))%mod;
}
}
cout<<ans<<endl;
}
return 0;
}
THE END;