1 条题解

  • 0
    @ 2025-10-22 16:45:07

    题解

    (请在此补充题目的中文题解与思路描述。)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MOD = 998244353;
    using int64 = long long;
    
    int addmod(int a, int b){ int s = a+b; if(s>=MOD) s-=MOD; return s; }
    int submod(int a, int b){ int s = a-b; if(s<0) s+=MOD; return s; }
    int mulmod(int64 a, int64 b){ return int(a*b%MOD); }
    int powmod(int a, long long e){
        int r=1;
        while(e){
            if(e&1) r=mulmod(r,a);
            a=mulmod(a,a);
            e>>=1;
        }
        return r;
    }
    int invmod(int a){ return powmod(a, MOD-2); }
    
    /* --------------------------------------------------------------- */
    /*  compute F(T) = probability that maximal rectangle area ≤ T      */
    
    int compute_F(long long N, int T, int q){          // q = x * inv(y) % MOD
        if (T==0){
            // all heights must be 0 -> each column height 0 with prob (1-q)
            int p0 = submod(1, q);
            return powmod(p0, N);
        }
    
        // pre‑compute powers of q up to T+1
        vector<int> powq(T+2);
        powq[0]=1;
        for(int i=1;i<=T+1;i++) powq[i]=mulmod(powq[i-1], q);
        int q_Tplus1 = powq[T+1];               // q^{T+1}
    
        // arrays for a = 1..T
        vector<int> pLow(T+2), pEq(T+2), pGeTrunc(T+2), L(T+2);
        for(int a=1;a<=T;a++){
            pLow[a] = submod(1, powq[a]);               // 1 - q^a
            pEq[a]  = mulmod(powq[a], submod(1, q));    // q^a * (1-q)
            pGeTrunc[a] = submod(powq[a], q_Tplus1);    // q^a - q^{T+1}
            L[a] = T / a;
        }
        // L[T+1] = 0 (not used)
        L[T+1]=0;
    
        // ----------  table R[a][len]  ----------
        vector<vector<int>> R(T+2);               // R[a][len] for 0 ≤ len ≤ L[a]
        R[T+1].assign(1,1);                       // R[T+1][0]=1
    
        for(int a=T;a>=1;a--){
            int maxlen = L[a];
            R[a].assign(maxlen+1,0);
            R[a][0]=1;
            for(int n=1;n<=maxlen;n++){
                int64 cur = mulmod(pEq[a], R[a][n-1]);   // first column = a
                int maxEll = min( (a+1<=T? L[a+1]:0), n);
                for(int ell=1; ell<=maxEll; ++ell){
                    int high = R[a+1][ell];               // probability of a high block
                    if (ell < n){
                        cur += (int64)high * pEq[a] % MOD * R[a][n-ell-1] % MOD;
                    }else{
                        cur += high;
                    }
                    if(cur>= (int64)MOD*MOD) cur %= MOD;
                }
                R[a][n] = int(cur % MOD);
            }
        }
    
        // ----------  initial values of U[1] ----------
        int d = T+1;                     // order of the recurrence
        vector<int> init(d,0);           // U[0..T]
        init[0]=1;
        for(int n=1;n<=T;n++){
            int64 cur = mulmod(pLow[1], init[n-1]);
            int maxEll = min(L[1], n);
            for(int ell=1; ell<=maxEll; ++ell){
                int r = R[1][ell];
                if (ell < n){
                    cur += (int64)r * pLow[1] % MOD * init[n-ell-1] % MOD;
                }else{
                    cur += r;
                }
                if(cur>= (int64)MOD*MOD) cur %= MOD;
            }
            init[n] = int(cur % MOD);
        }
    
        if (N <= T) return init[N];
    
        // ----------  recurrence coefficients ----------
        // U[n] = Σ_{i=0}^{d-1} coeff[i] * U[n-i-1]
        vector<int> coeff(d,0);
        coeff[0] = pLow[1];
        for(int k=1;k<=T;k++){
            coeff[k] = mulmod(pLow[1], R[1][k]);
        }
    
        // ----------  Kitamasa :  compute x^N (mod characteristic) ----------
        auto combine = [&](const vector<int>& A, const vector<int>& B){
            vector<int64> tmp(2*d-1,0);
            for(int i=0;i<d;i++) if(A[i])
                for(int j=0;j<d;j++) if(B[j]){
                    tmp[i+j] += (int64)A[i]*B[j];
                    if(tmp[i+j] >= (int64)MOD*MOD) tmp[i+j] %= MOD;
                }
            // reduction
            for(int i=2*d-2;i>=d;i--){
                if(tmp[i]==0) continue;
                int64 v = tmp[i] % MOD;
                for(int j=0;j<d;j++){
                    tmp[i-1-j] += v * coeff[j];
                    if(tmp[i-1-j] >= (int64)MOD*MOD) tmp[i-1-j] %= MOD;
                }
            }
            vector<int> res(d,0);
            for(int i=0;i<d;i++) res[i] = int(tmp[i]%MOD);
            return res;
        };
    
        // binary exponentiation of polynomial x
        vector<int> base(d,0), result(d,0);
        base[1]=1;               // x
        result[0]=1;             // 1
        long long e = N;
        while(e){
            if(e&1) result = combine(result, base);
            base = combine(base, base);
            e >>= 1;
        }
        // result now holds coefficients of x^N  (degree < d)
        int64 ans = 0;
        for(int i=0;i<d;i++){
            ans += (int64)result[i] * init[i];
            if(ans >= (int64)MOD*MOD) ans %= MOD;
        }
        return int(ans % MOD);
    }
    
    /* --------------------------------------------------------------- */
    
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        long long N;
        int K, x, y;
        if(!(cin>>N>>K>>x>>y)) return 0;
        int q = mulmod(x, invmod(y));          // q = x / y  (mod MOD)
    
        int FK = compute_F(N, K, q);
        int FK1 = (K==0 ? 0 : compute_F(N, K-1, q));
        int answer = submod(FK, FK1);
        cout << answer << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    3713
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者