# 「atcoder - ARC089F」ColoringBalls

## solution

（1）如果全为红色，则只需要一次 'r' 操作。

（2）否则，至少需要一次 'r' 操作 + 一次 'b' 操作。

## code

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

#define rep(i, x, n) for(int i=x;i<=n;i++)
#define pr make_pair
#define fi first
#define se second

const int MOD = int(1E9) + 7;
const int MAX = 420000;

inline int add(int x, int y) {x += y; return x >= MOD ? x - MOD : x;}
inline int sub(int x, int y) {x -= y; return x < 0 ? x + MOD : x;}
inline int mul(int x, int y) {return (int) (1LL * x * y % MOD);}
int mpow(int b, int p) {
int r; for(r=1;p;p>>=1,b=mul(b,b))
if( p & 1 ) r = mul(r, b);
return r;
}

struct node{int x[40], cnt;}st[MAX + 5];

int l[75], tot, N, K;
void dfs(int s, node a, int x) {
st[++tot] = a;
for(int i=x;i<=N&&l[i]<=s;i++)
a.x[a.cnt++] = i, dfs(s - l[i], a, i), a.x[--a.cnt] = i;
}

int f[MAX + 5], fct[505], ifct[505], c[505][505];
void init() {
rep(i, 0, 500) rep(j, 0, i)
c[i][j] = (j == 0 ? 1 : add(c[i - 1][j], c[i - 1][j - 1]));
fct[0] = 1; rep(i, 1, 500) fct[i] = mul(fct[i - 1], i);
ifct[500] = mpow(fct[500], MOD - 2);
for(int i=499;i>=0;i--) ifct[i] = mul(ifct[i + 1], i + 1);

l[1] = 2; rep(i, 2, N) l[i] = (i - 1) << 1; dfs(N, (node){}, 1);
rep(i, 1, tot) {
int a = 1, b = 0, t = 1, p = 1;
rep(j, 1, st[i].cnt - 1) {
if( st[i].x[j] != st[i].x[j-1] )
t = mul(t, ifct[p]), p = 1;
else p++;
}
t = mul(t, ifct[p]);
rep(j, 0, st[i].cnt - 1) {
b += l[st[i].x[j]];
if( st[i].x[j] != 1 ) a += 2;
}
f[i] = mul(mul(fct[st[i].cnt], t), c[N + a - 1][a + b - 1]);
}
//	printf("%d\n", tot);
}

int tg[75], q[75]; char s[75];
int main() {
scanf("%d%d%s", &N, &K, s + 1), N++, init();

int ans = 0;
rep(i, 1, tot) {
int cnt1 = 0, pos = -1;
rep(j, 0, st[i].cnt - 1) {
if( st[i].x[j] != 1 ) {
pos = j;
break;
} else cnt1++;
}

int hd = 1, tl = 0, p = st[i].cnt - cnt1;
rep(j, 1, K) tg[j] = -1;
for(int j=1;p&&j<=K;j++) {
if( s[j] == 'r' ) q[++tl] = j;
else if( hd <= tl ) tg[q[hd++]] = 0, tg[j] = 1, p--;
}

int cnt[2] = {}; bool flag = true;
for(int j=K;j>=1;j--) {
if( tg[j] == -1 ) cnt[s[j] == 'r' ? 0 : 1]++;
else if( tg[j] == 1 ) {
int tmp = st[i].x[pos] - 2;
while( cnt[1] && tmp ) cnt[1]--, tmp--;
while( cnt[0] && tmp ) cnt[0]--, tmp--;
if( tmp ) {
flag = false;
break;
}
pos++;
}
}

if( flag && cnt[0] >= cnt1 && p == 0 ) ans = add(ans, f[i]);
}
printf("%d\n", ans);
}


## details

posted @ 2020-07-03 20:19  Tiw_Air_OAO  阅读(22)  评论(0编辑  收藏