P4562 [JXOI2018]遊戲
阿新 • • 發佈:2021-11-02
給定一個區間[L,R],每次可以去除區間一個數字及其它的倍數,求把整個區間消去的步數的所有情況的和
我們可以定義整個區間偽素數為這個區間沒有它的倍數的數,那麼一個消去順序的步數就是最後面的偽素數。那麼我們可以列舉這個最右邊的偽素數的質數的位置為i,依次算出每個位置的貢獻,方案數
設偽素數的個數為sum,區間長度為n
那麼總答案為
求偽素數的方法可以用埃氏篩
時間複雜度\(O(n \ log \ log \ n)\)
lxl inv_fac[N], fac[N]; lxl len, sum, ans, temp; bool v[N]; inline void init() { fac[0] = 1; rep(i, 1, len) { fac[i] = fac[i - 1] * i % mod; } inv_fac[len] = Quick_Pow(fac[len], mod - 2); drp(i, len - 1, 0) { inv_fac[i] = inv_fac[i + 1] * (i + 1) % mod; } rep(i, L, R) { if(v[i]) continue; ++sum; for(int j(i << 1); j <= R; j += i) { v[j] = 1; } } } inline lxl C(int n, int m) { if(n < m) { return 0; } return fac[n] * inv_fac[m] % mod * inv_fac[n - m] % mod; } int main() { read(L); read(R); len = R - L + 1; init(); rep(i, sum, len) { temp = 1ll * i * sum % mod; temp = temp * C(len - sum, len - i) % mod; temp = temp * fac[len - i] % mod * fac[i - 1] % mod; ans = (ans + temp) % mod; } out(ans, '\n'); return 0; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15500627.html