【YBTOJ】【Luogu P2480】[SDOI2010]古代豬文
阿新 • • 發佈:2020-12-10
題目連結:
題目大意:
求:
\[m^{\sum_{d|n}C_{n}^{d}}\bmod 999911659 \]正文:
這種指數一坨式子外面還套個模的一般考慮尤拉定理的推論或擴充套件尤拉定理。這個用擴充套件尤拉定理明顯搞不了,就考慮用尤拉定理的推論。
\[m^{\sum_{d|n}C_{n}^{d}}\equiv m^{\sum_{d|n}C_{n}^{d}\bmod999911658}\pmod{999911659} \]還是難搞啊這指數一坨。但是我們發現裡面有個組合數,這提示了我們可以 Lucas 定理優化,但是這裡面的這個模數這麼大一坨,還不如不用,所以考慮拆這個模數。在嘗試的過程中你可能會試著將 \(999911658\)
其中 \(a_i\) 就是要利用 Lucas 求出來的 \(\sum_{d|n}C_{n}^{d}\)
程式碼:
ll M = 999911659ll, ans; ll m_[5] = {0, 2ll, 3ll, 4679ll, 35617ll}, a[5]; ll prod[N]; void init(ll p) { prod[0] = 1; for (register int i = 1; i <= p + 10; i++) prod[i] = (prod[i - 1] * i) % p; } ll exgcd(ll a, ll b, ll &x, ll &y) { if(b == 0) { x = 1, y = 0; return a; } int gcd = exgcd(b, a % b, y, x); y -= a / b * x; return gcd; } ll qpow(ll a, ll b, ll p) { a %= p; ll ans = 1; for(; b; b >>= 1, a = a * a % p) if(b & 1) ans = ans * a % p; return ans; } ll C(ll n, ll m, ll p) { if(m > n)return 0; if(n == 0) return 1; return ((prod[n] * qpow(prod[m], p - 2, p)) % p * qpow(prod[n - m], p - 2, p) % p); } ll Lucas(ll n, ll m, ll p) { if(!m) return 1; return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p; } int main() { scanf ("%d%d", &n, &m); if (m % M == 0) {puts("0"); return 0;} // 特判 m 是 999911659 因數 for (int i = 1; i <= 4; i++) { init(m_[i]); for (int j = 1; j * j <= n; j++) { if(n % j) continue; (a[i] += Lucas(n, j, m_[i])) %= m_[i]; if(j * j == n) continue; (a[i] += Lucas(n, n / j, m_[i])) %= m_[i]; } } for (int i = 1; i <= 4; i++) { ll t = 0, y; exgcd(M / m_[i], m_[i], t, y); ans += a[i] * (M / m_[i]) * (t < 0? t + m_[i]: t); } printf("%lld", qpow(m, ans, M)); return 0; }