BZOJ3601 一个人的数论
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3601 一个人的数论相关的知识,希望对你有一定的参考价值。
BZOJ3601 一个人的数论
题意
\\[ ans = \\sum _ {i \\nmid n} i ^ d \\]
\\[ n = \\prod _ {i = 1} ^ {w} p _ i ^ {\\alpha _ i} \\]
输入
第一行给出$d$, $w$
接下来$w$行,第$i + 1$行给出$p _ i$, $\\alpha _ i$
输出
题目所求的$ans$
样例输入
3 2
2 1
5 1
样例输出
1100
围观大神题解:https://www.cnblogs.com/jianglangcaijin/p/4033399.html
1 #include<bits/stdc++.h> 2 using namespace std; 3 template <class _T> inline void read(_T &_x) { 4 int _t; bool flag = false; 5 while ((_t = getchar()) != ‘-‘ && (_t < ‘0‘ || _t > ‘9‘)) ; 6 if (_t == ‘-‘) _t = getchar(), flag = true; _x = _t - ‘0‘; 7 while ((_t = getchar()) >= ‘0‘ && _t <= ‘9‘) _x = _x * 10 + _t - ‘0‘; 8 if (flag) _x = -_x; 9 } 10 typedef long long LL; 11 const int maxw = 1010; 12 const int maxd = 110; 13 const int mod = 1e9 + 7; 14 inline int mul(int a, int b) {return (int)((LL)a * b % mod); } 15 inline int add(int a, int b) { 16 a += b; 17 if (a < 0) a += mod; if (a >= mod) a -= mod; 18 return a; 19 } 20 int qpow(LL a, LL b) { 21 if (b < 0) return qpow(qpow(a, mod - 2), -b); 22 LL ret = 1; 23 while (b) { 24 if (b & 1) (ret *= a) %= mod; 25 (a *= a) %= mod, b >>= 1; 26 } 27 return (int)ret; 28 } 29 int H(int i, int p, int a, int d) { 30 return mul(qpow(p, (LL)a * i), add(1, -qpow(p, d - i))); 31 } 32 int A[maxd][maxd], X[maxd]; 33 inline void init(int d) { 34 static int sum[maxd]; 35 sum[0] = 0; 36 for (int i = 1; i <= d + 2; ++i) { 37 sum[i] = add(sum[i - 1], qpow(i, d)); 38 A[i - 1][d + 2] = sum[i], A[i - 1][0] = 1; 39 for (int j = 1; j <= d + 1; ++j) A[i - 1][j] = mul(A[i - 1][j - 1], i); 40 } 41 for (int i = 0, tmp; i <= d + 1; ++i) { 42 int to = i; 43 while (to <= d + 1 && !A[to][i]) break; 44 if (i != to) swap(A[i], A[to]); 45 for (int j = 0; j <= d + 1; ++j) if (j != i && A[j][i]) { 46 tmp = mul(A[j][i], qpow(A[i][i], mod - 2)); 47 for (int k = 0; k <= d + 2; ++k) A[j][k] = add(A[j][k], -mul(tmp, A[i][k])); 48 } 49 } 50 for (int i = 0; i <= d + 1; ++i) { 51 X[i] = mul(A[i][d + 2], qpow(A[i][i], mod - 2)); 52 } 53 } 54 int d, w, p[maxw], a[maxw]; 55 int main() { 56 //freopen(".in", "r", stdin); 57 //freopen(".out", "w", stdout); 58 read(d), read(w); 59 for (int i = 1; i <= w; ++i) read(p[i]), read(a[i]); 60 init(d); 61 int ans = 0; 62 for (int i = 1; i <= d + 1; ++i) { 63 int ret = X[i]; 64 for (int j = 1; j <= w; ++j) 65 ret = mul(ret, H(i, p[j], a[j], d)); 66 ans = add(ans, ret); 67 } 68 cout << ans << endl; 69 return 0; 70 }
以上是关于BZOJ3601 一个人的数论的主要内容,如果未能解决你的问题,请参考以下文章
[bzoj3601] 一个人的数论 [莫比乌斯反演+高斯消元]
BZOJ 3136 3136: [Baltic2013]brunhilda (数论?)