abc135d 模13餘5的數的個數

chenfy27發表於2024-03-15

給定一個由0~9以及?組成的字串,其中的?可以替換成0~9中任意1個數字,問有多少種情況使得這個數字模13的餘數為5?結果對1e9+7取模。注意允許s有前導0。
1<=|s|<=1e5

記dp[i][j]表示前i個數字構成的數,模13餘j的方案數。如果s[i]是數字,直接轉移;如果是問題,列舉0~9所有可能分別列舉,總時間複雜度O(13n)。這裡使用的刷表法。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=b;i>=a;i--)

template<int MOD>
struct MInt {
    int x;
    int norm(int u) const {u%=MOD; if(u<0) u+=MOD; return u;}
    MInt(int v=0):x(norm(v)) {}
    int val() const {return x;}
    MInt operator-() const {return MInt(norm(MOD-x));}
    MInt inv() const {assert(x!=0); return power(MOD-2);}
    MInt &operator*=(const MInt &o) {x=norm(x*o.x); return *this;}
    MInt &operator+=(const MInt &o) {x=norm(x+o.x); return *this;}
    MInt &operator-=(const MInt &o) {x=norm(x-o.x); return *this;}
    MInt &operator/=(const MInt &o) {*this *= o.inv(); return *this;}
    friend MInt operator*(const MInt &a, const MInt &b) {MInt ans=a; ans*=b; return ans;}
    friend MInt operator+(const MInt &a, const MInt &b) {MInt ans=a; ans+=b; return ans;}
    friend MInt operator-(const MInt &a, const MInt &b) {MInt ans=a; ans-=b; return ans;}
    friend MInt operator/(const MInt &a, const MInt &b) {MInt ans=a; ans/=b; return ans;}
    friend std::istream &operator>>(std::istream &is, MInt &a) {int u; is>>u; a=MInt(u); return is;}
    friend std::ostream &operator<<(std::ostream &os, const MInt &a) {os<<a.val(); return os;}
    MInt power(int b) const {int r=1, t=x; while(b){if(b&1) r=r*t%MOD; t=t*t%MOD; b/=2;} return MInt(r);}
};
using mint = MInt<1000000007>;

const int N = 100005;
mint dp[N][13];
string s;
void solve() {
    cin >> s;
    int n = s.size();
    dp[0][0] = 1;
    rep(i,0,n-1) rep(j,0,12) {
        if (s[i] == '?') {
            rep(k,0,9) {
                int u = (j * 10 + k) % 13;
                dp[i+1][u] += dp[i][j];
            }
        } else {
            int k = (j * 10 + s[i] - '0') % 13;
            dp[i+1][k] += dp[i][j];
        }
    }
    cout << dp[n][5] << "\n";
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

相關文章