CodeForces 794 G.Replace All

CodeForces 794 G.Replace All

解題思路c++

首先若是字符串 \(A, B\) 沒有匹配,那麼二元組 \((S, T)\) 合法的一個必要條件是存在正整數對 \((x,y)\),使得 \(xS=yT\),其中 \(xS\) 是將字符串 \(S\) 複製 \(x\) 遍後獲得的字符串,\(yT\) 是將字符串 \(T\) 複製 \(T\) 遍後獲得的字符串。因爲 \(A,B\) 直接匹配的狀況比較容易討論,下面沒有特殊說明,都是 \(A,B\) 沒有直接匹配的狀況。git

這個條件的實際意義是經過這個二元組 \((S,T)\) 轉化後,能將 \(x\)\('a'\) 組成的子串與 \(y\)\('b'\) 組成的子串通配,必要性能夠根據這個感性理解,下面來證實知足這個條件的二元組的一些性質。spa

對於字符串 \(C=xS=yT\) ,顯然存在週期 \(x\) 和週期 \(y\) ,根據週期定理 \(\gcd(x,y)\) 也是 \(C\) 的一個週期,其也是 \(S,T\) 的一個週期,咱們令 \(C[1:\gcd(x,y)]=D\) ,那麼 \(S=\dfrac{y}{\gcd(x,y)}D,T=\dfrac{x}{\gcd(x,y)}D\) 。用 \(+\) 表示字符串的拼接,能夠獲得 \(S+T=T+S=\dfrac{xy}{\gcd(x,y)}D\) 。也就是用這個二元組轉化後,任意兩個相鄰的字符 \('a','b'\) 交換後獲得的字符串不變,最終的字符串只與字符 \('a','b'\) 的數量用關。code

假設將 \('?'\) 填好以後,令 \(\Delta a\) 表示 \(A\)\('a'\) 的數量與 \(B\)\('a'\) 的數量之差,\(\Delta b\) 表示 \(A\)\('b'\) 的數量與 \(B\)\('b'\) 的數量之差,此時若是 \(\Delta a \Delta b\geq0\)\(\Delta a,\Delta b\) 不一樣時等於 \(0\) ,那麼不存在知足條件的合法二元組。字符串

若是 \(\Delta a=0,\Delta b=0\) ,那麼任意一個知足條件的合法二元組均可以,其中一個 \(\gcd(x,y)=g\) 的合法二元組的方案數就是 \(2^g\) (考慮字符串 \(D\) 的每一位是怎麼填的便可),那麼只須要容斥出全部 \(\gcd(x,y)=i\) 的對數便可。get

不然,知足條件的 \(x, y\) 的比值是 \(\dfrac{|\Delta a|}{|\Delta b|}\) ,令 \(g=\gcd(\Delta a,\Delta b)\) ,枚舉 \(D\) 的長度,方案數就是
\[ 2^{\dfrac{n}{\dfrac{\max(|\Delta a|,|\Delta b|)}{g}}+1}-2 \]
如今考慮 \('?'\) 的影響,令 \(cntA\)\(A\)\('?'\) 個數,\(cntB\)\(B\)\('?'\) 個數,那麼填 \('?'\) 的影響就是讓 \(\Delta a\) 加上一個整數 \(d\)\(\Delta b\) 加上 \(cntA-cntB-d\),這樣選的方案數是 \({cntA+cntB}\choose{cntB+d}\) ,推導能夠把方案數的和式列出來而後展開,固然你要作卷積也是能夠的。(模數 \(10^9+7\)) ,而後只須要枚舉一下 \('?'\) 貢獻的 \(d\) 的值這一部分就算出來了。it

注意前面提到的都是 \(A,B\) 沒有直接匹配的狀況,對於 \(A,B\) 在填完 \('?'\) 以後能直接匹配的狀況,全部的二元組都是合法的,只須要把以前沒算的部分在這裏算上便可,總的複雜度是 \(\mathcal O(n\log n)\)class

code

/*program by mangoyang*/
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int ch = 0, f = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    if(f) x = -x;
}
const int N = 1000005, mod = 1e9 + 7;
char s[N], t[N];
int inv[N], js[N], pw[N], f[N], cnts, cntt, da, db, lens, lent, n, ans, total;
inline int Pow(int a, int b){
    int ans = 1;
    for(; b; b >>= 1, a = 1ll * a * a % mod)
        if(b & 1) ans = 1ll * ans * a % mod;
    return ans;
}
inline int C(int x, int y){ 
    return 1ll * js[x] * inv[y] % mod * inv[x-y] % mod; 
}
int main(){
    scanf("%s", s + 1), scanf("%s", t + 1), read(n);
    lens = strlen(s + 1), lent = strlen(t + 1);
    for(int i = 1; i <= lens; i++){
        if(s[i] == 'A') da++; if(s[i] == 'B') db++; if(s[i] == '?') cnts++;
    }
    for(int i = 1; i <= lent; i++){
        if(t[i] == 'A') da--; if(t[i] == 'B') db--; if(t[i] == '?') cntt++;
    }
    inv[0] = js[0] = pw[0] = 1;
    for(int i = 1; i <= n + 1; i++) pw[i] = 2ll * pw[i-1] % mod;
    for(int i = 1; i <= lens + lent; i++) 
        js[i] = 1ll * js[i-1] * i % mod, inv[i] = Pow(js[i], mod - 2);
    for(int i = n; i; i--){
        f[i] = 1ll * (n / i) * (n / i) % mod;
        for(int j = i + i; j <= n; j += i) (f[i] += mod - f[j]) %= mod;
        total = (total + 1ll * f[i] * pw[i] % mod) % mod;
    }
    for(int d = -cntt; d <= cnts; d++){
        int A = da + d, B = db + cnts - cntt - d, x = C(cnts + cntt, cntt + d);
        if(!A && !B) (ans += 1ll * x * total % mod) %= mod;
        if(1ll * A * B >= 0) continue;
        int g = __gcd(abs(A), abs(B)); 
        A = abs(A) / g, B = abs(B) / g;
        (ans += (1ll * x * (pw[n/max(A,B)+1] - 2) + mod) % mod) %= mod;
    }
    if(lens == lent){
        int flag = 1, res = 1;
        for(int i = 1; i <= lens; i++){
            if(s[i] != '?' && t[i] != '?' && s[i] != t[i]) flag = 0;
            if(s[i] == '?' && t[i] == '?') res = 2ll * res % mod;
        }
        if(!flag) return cout << ans << endl, 0;
        (ans += 1ll * res * (1ll * (pw[n+1] - 2) * (pw[n+1] - 2) % mod - total) % mod) %= mod;
        ans = (ans % mod + mod) % mod;
    }
    cout << ans << endl;
    return 0;
}
相關文章
相關標籤/搜索