[CF794G] Replace All 【Combination Mathematics】 【Number Theory】

Hey, did I have a CF without writing a solution?

For not consider ?the case that a method is known to \ (c, d \) is ?replaced after the letter embodiment, how to find a legitimate \ (01 \) string tuple \ ((s, t) \) Quantity.

Set \ (a_x, b_x \) denote the string \ (X \) in the A, Bnumber, consider the following two cases:

  1. \(a_c< a_d\)\(b_c> b_d\)
  2. \(a_c>a_d\)\(b_c<b_d\)
  3. \ (a_c = a_d \) and \ (b_c = b_d \) .

Note that \ (| s |, | t | \ geq 1 \) , so for the other three cases, no matter how \ (| s |, | t | \) is arranged, it is impossible to replace the \ ( 01 \) The sequence length is equal. The first two cases are actually symmetrical, so only the first one is considered here.

In order to make the length of the replaced \ (01 \) sequence equal, you can get \ ((a_d-a_c) | s | = (b_c-b_d) | t | \) . Let \ (g = \ gcd (a_d-a_c, b_c-b_d) \) , it is not difficult to find, the minimum value of \ ( | s | \) \ (m_s = \ frac {b_c-b_d} {g} \) , Corresponding minimum value of \ (| t | \) \ (m_t = \ frac {a_d-a_c} {g} \) , you might as well set \ (m_t \ leq m_s \) .

Since \ (\ gcd (m_s, m_t) = 1 \) , it is not difficult to find that any \ (x \ in [0, m_s) \) has a unique \ (y \ in [0, m_s) \) , Make \ (y \ cdot m_t \ equiv x \ pmod {m_s} \) . In other words, for a continuous \ (M_t \) a \ (S \) sequences, we continue to intercept length from the foremost \ (M_t \) of the section, taken down exactly \ (S \ ) of each cycle (i.e., the \ (S \) to take down a prefix, received intact \ (S \) below). It is not difficult to find that in this case, \ (s, t \) has only two schemes: all composed of \ (0 \) , or all composed of \ (1 \) . It is not difficult to find that if you copy this sequence into positive integer passes, and then insert some \ (s \) or \ (t \) in certain positions , as long as these strings are intercepted separately during interception, the above properties still hold.

The last sentence of the paragraph above, in fact expressed, for any situation which satisfies \ (1 \) (in case of \ (2 \) similar), determined the \ (a_c, a_d, b_c, b_d \) a \ ( c, d \) Scheduler string, we are only concerned \ (a_d-a_c \) and (b_c-b_d \) \ value, but does not care about these A, Bthe specific location. And we can calculate the corresponding number of \ (s, t \) schemes. Specifically, first of all \ (| s |, | t | \) are multiples of \ (m_s, m_t \) respectively, and \ (| s | = k \ cdot m_s, | t | = k \ cdot m_t \) At that time, we have \ (2 ^ k \) schemes (because the non-coprime parts cannot be obtained in the above way, so these positions happen to be divided into \ (k \) independent connected blocks of values). This is a simple sum of proportional sequences.

Therefore, we can violently enumerate the value of \ (a_d-a_c \) . Not difficult to find, due ?in \ (c, d \) number is determined, we can directly calculate \ (b_c-b_d \) values. Another problem is that there may be multiple groups of \ ((a_c, a_d, b_c, b_d) \) . But the emotional understanding of what can be found, if you want to keep (a_d-a_c \) \ and \ (b_c-b_d \) unchanged, then each in \ (c \) in more than one ?replaced A, it must \ (d \ ) in a Major ?replaced B. In other words, \ (a_c + b_d \) values are determined, and in this case, will be ?replaced by the number of letters is a program with only \ (a_c + b_d \) related to the number of combinations (in fact it is the (Vandermonde's identity).

Now there is still the situation \ (3 \) . For the case of \ (3 \) , it is found that \ (| s |, | t | \) has no restrictions, so we have to find the legal \ ( \ ((s |, | t |) \) for each \ ( s, t \) quantity. In fact, similar to the discussion above, if \ (\ gcd (| s |, | t |) = 1 \) , it can be proved that \ (s, t \) is also either all \ (0 \) or all \ ( 1 \) . Expanding a bit, we can find that we are asking for \ (\ sum_ {| s | = 1} ^ {n} \ sum_ {| t | = 1} ^ n 2 ^ {\ gcd (| s |, | t |)} \) . This is very simple, and I will not repeat them here. And the ?alternative embodiment the number of letters, in fact, is the same as above.

However, there is one last pit. If \ (C = D \) , which means that each position A/Bare equal, then any one of length does not exceed \ (n-\) a \ ((s, t) \ ) are clearly satisfies the condition. Therefore, this part should be deducted from the above and calculated separately.

Code:

#include <bits/stdc++.h>
#define R register
#define mp make_pair
#define ll long long
#define pii pair<int, int>
using namespace std;
const int mod = 1e9 + 7, N = 310000, M = N << 1;

int n, m, k, sa, sb, ta, tb, sc, tc, ispr[N], mu[N];
ll fac[M], inv[M];
char s[N], t[N];
vector<int> prime;

inline int addMod(int a, int b) {
	return (a += b) >= mod ? a - mod : a;
}

inline ll quickpow(ll base, ll pw) {
	ll ret = 1;
	while (pw) {
		if (pw & 1) ret = ret * base % mod;
		base = base * base % mod, pw >>= 1;
	}
	return ret;
}

template <class T>
inline void read(T &x) {
	x = 0;
	char ch = getchar(), w = 0;
	while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
	while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	x = w ? -x : x;
	return;
}

inline void initComb(int n) {
	fac[0] = 1;
	for (R int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
	inv[n] = quickpow(fac[n], mod - 2);
	for (R int i = n; i; --i) inv[i - 1] = inv[i] * i % mod;
}

inline ll comb(int n, int m) {
	if (m < 0 || n < m) return 0;
	return fac[n] * inv[m] % mod * inv[n - m] % mod;
}

int getGcd(int a, int b) {
	return b ? getGcd(b, a % b) : a;
}

inline ll calc(int x) {
	return addMod(quickpow(2, x + 1), mod - 2);
}

inline int sign(int x) {
	return x < 0 ? -1 : x > 0;
}

void initPrime(int n) {
	mu[1] = 1;
	for (R int i = 2, k; i <= n; ++i) {
		if (!ispr[i])
			mu[i] = -1, prime.push_back(i);
		for (auto &j : prime) {
			if ((k = i * j) > n) break;
			ispr[k] = 1;
			if (i % j == 0) break;
			mu[k] = addMod(mod, -mu[i]);
		}
	}
	return;
}

inline ll sq(ll x) {
	return x * x % mod;
}

int main() {
	scanf("%s%s", s + 1, t + 1), read(k);
	n = strlen(s + 1), m = strlen(t + 1);
	if (n < m) swap(s, t), swap(n, m);
	initComb(n + m), initPrime(k);
	for (R int i = 1; i <= n; ++i)
		sa += s[i] == 'A', sb += s[i] == 'B', sc += s[i] == '?';
	for (R int i = 1; i <= m; ++i)
		ta += t[i] == 'A', tb += t[i] == 'B', tc += t[i] == '?';
	ll ans = 0;
	for (R int i = sa - ta - tc; i <= sa - ta + sc; ++i) {
		int j = m - n + i;
		if (i == 0 && j == 0) {
			ll w = 0, pw = 1;
			for (R int d = 1; d <= k; ++d) {
				pw = addMod(pw, pw);
				for (R int u = 1, v = d; v <= k; ++u, v += d)
					w = (w + pw * mu[u] % mod * sq(k / v)) % mod;
			}
			pw = 1;
			for (R int d = 1; pw && d <= n; ++d) {
				if (s[d] == '?' && t[d] == '?')
					pw = addMod(pw, pw);
				else if (s[d] != '?' && t[d] != '?' && s[d] != t[d])
					pw = 0;
			}
			ans = (ans + w * (comb(sc + tc, ta + tc - sa + i) + mod - pw)) % mod;
			ans = (ans + pw * sq(calc(k))) % mod;
		}
		if (sign(i) * sign(j) != 1) continue;
		ans = (ans + calc(k / ((i < 0 ? j : i) / getGcd(i, j))) * comb(sc + tc, ta + tc - sa + i)) % mod;
	}
	cout << ans << endl;
	return 0;
}

Guess you like

Origin www.cnblogs.com/suwakow/p/12748947.html