loj #6247. 九个太阳

$\sum\limits_{i=1}^n [k | i] \times C_n^i$

膜 $998244353$

$n \leq 10^{15},k \leq 2^{20}$

$k$ 是 $2$ 的正整数次方

 

sol:

“不看题解拿头做” 系列

考虑构造一个序列 $a_i$ 满足只有 $[k|i]$ 时是 $1$,其它时候是 $0$

之后就开始神仙了起来

 

构造 $k$ 次单位根 $\omega _k = g^{\frac{p-1}{k}}$,发现 $\frac{1}{k} \times \sum\limits_{j=0}^{k-1} \omega _k^{i \times j} = [k | i]$

代入原式得到 $\sum\limits_{i=1}^n \frac{1}{k} \times \sum\limits_{j=0}^{k-1} \omega _k^{i \times j} \times C_n^i$

根据二项式定理 $\sum\limits_{i=0}^n C_n^i \times x^i = (x+1)^n$,可以化简

$\frac{1}{k} \times \sum\limits_{j=0}^{k-1} (\omega_k ^j + 1)^n$

这就可以直接求了

#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
inline LL read() {
    LL x = 0, f = 1; char ch = getchar();
    for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -f;
    for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
    return x * f;
}
const int mod = 998244353;
inline int ksm(int x, int t) {
    int res = 1;
    for(; t; x = 1LL * x * x % mod, t = t >> 1) if(t & 1) res = 1LL * x * res % mod;
    return res;
}
int main() {
    LL n = read() % (mod-1), k = read();
    int ans = 0;
    int wn = ksm(3, (mod-1) / k), w = ksm(3, (mod-1) / k);
    rep(i, 0, k-1) {
        (ans += ksm(w + 1, n)) %= mod;
        w = 1LL * w * wn % mod;
    }
    ans = 1LL * ans * ksm(k, mod - 2) % mod;
    cout << ans << endl;
}
View Code

 

posted @ 2019-03-07 17:26  探险家Mr.H  阅读(453)  评论(0编辑  收藏  举报