51NOD 序列求和 V5题解
来源:互联网 发布:乃木坂网络直播电视剧 编辑:程序博客网 时间:2024/05/17 03:40
被数论くん搞得头大的本宝宝来写一发数论题~
51NOD 序列求和 V5
若
接下来,我们用符号
若
这里先写一个引理:
将
这样,分子和分母的部分都可以预处理出来,复杂度
若
下面我们证明一个结论,对
我们再来证明一个引理:对
在上一部分的讨论中,我们已经知道,作为一个
我们又有:
通过上面两个等式,我们就可以通过解一个一元一次方程来得到
#include<bits/stdc++.h>#define ll long longconst int N = 200010;const int moder = 985661441;int power(int a, ll index){ int ans = 1; while (index){ if (index & 1) ans = 1ll * ans * a % moder; a = 1ll * a * a % moder; index >>= 1; } return ans;}int min[N], x[N], f[N], F[N], prefix[N], suffix[N], fac[N], inv[N], t, k;ll n, r;std::vector <int> prime;void calc(){ prefix[0] = suffix[k + 1] = 1; for (int i = 1; i <= k + 1; ++ i){ prefix[i] = 1ll * prefix[i - 1] * ((n - i + 1) % moder) % moder; } for (int i = k; i >= 0; -- i){ suffix[i] = 1ll * suffix[i + 1] * ((n - i - 1) % moder) % moder; } int ans = 0; for(int i = 0; i <= k + 1; ++ i){ int now = 1ll * f[i] * inv[i] % moder * inv[k - i + 1] % moder; now = 1ll * now * prefix[i] % moder * suffix[i] % moder; if ((k - i + 1) & 1) now = (moder - now) % moder; ans = (ans + now) % moder; } printf("%d\n", ans);}void _calc(){ int inv_r = power(r, moder - 2); int sum_a = 1, sum_b = 0; prefix[0] = 1; suffix[0] = 0; for (int i = 1; i <= k + 1; ++ i){ prefix[i] = 1ll * prefix[i - 1] * inv_r % moder; suffix[i] = 1ll * (suffix[i - 1] + x[i]) * inv_r % moder; int coe = 1ll * fac[k + 1] % moder * inv[i] % moder * inv[k + 1 - i] % moder; if (i & 1) coe = (moder - coe) % moder; sum_a = (sum_a + 1ll * coe * prefix[i]) % moder; sum_b = (sum_b + 1ll * coe * suffix[i]) % moder; } int _x = 1ll * (moder - sum_b) * power(sum_a, moder - 2) % moder; for (int i = 0; i <= k; ++ i) F[i] = (1ll * prefix[i] * _x + suffix[i]) % moder; prefix[0] = suffix[k] = 1; for (int i = 1; i <= k; ++ i){ prefix[i] = 1ll * prefix[i - 1] * ((n - i + 1) % moder) % moder; } for (int i = k - 1; i >= 0; -- i){ suffix[i] = 1ll * suffix[i + 1] * ((n - i - 1) % moder) % moder; } int ans = 0; for(int i = 0; i <= k; ++ i){ int now = 1ll * F[i] * inv[k - i] % moder * inv[i] % moder; now = 1ll * now * prefix[i] % moder * suffix[i] % moder; if ((k - i) & 1) now = (moder - now) % moder; ans = (ans + now) % moder; } ans = (1ll * ans * power(r, n) - F[0] + moder) % moder; ans = 1ll * ans * r % moder; printf("%d\n", ans);}int main(){ scanf("%d", &t); fac[0] = fac[1] = inv[0] = inv[1] = 1; for (int i = 2; i < N; ++ i){ fac[i] = 1ll * i * fac[i - 1] % moder; inv[i] = power(fac[i], moder - 2); if (!min[i]){ min[i] = i; prime.push_back(i); } for (int j = 0; j < prime.size() && prime[j] <= i && prime[j] * i < N; ++ j) min[prime[j] * i] = prime[j]; } while (t --){ scanf("%d%I64d%I64d", &k, &n, &r); r %= moder; if (r == 0){ puts("0\n"); continue; } x[1] = 1; int now = r; f[1] = r; for (int i = 2; i < k + 10; ++ i){ now = 1ll * now * r % moder; if (min[i] == i) x[i] = power(i, k); else x[i] = 1ll * x[min[i]] * x[i / min[i]] % moder; f[i] = (f[i - 1] + 1ll * x[i] * now) % moder; } if (n < 1ll * (k + 10)){ printf("%d\n", f[n]); continue; } if (r == 1){ calc(); continue; } _calc(); } return 0;}
0 0
- 51NOD 序列求和 V5题解
- 51nod 1228 序列求和
- 51Nod-1228-序列求和
- [伯努利数] 51Nod 1258 序列求和 V4
- 51nod 1258 序列求和 V4 拉格朗日插值法求自然数幂和
- 51Nod-1712-区间求和
- 51Nod 1712 区间求和
- 51nod 1712 区间求和
- [51nod 1258] [伯努利数] [多项式求逆] [任意模数NTT] 序列求和 V4
- [51nod1228]序列求和
- [贪心]51Nod 1241 题解
- [51nod-1432]独木舟 题解
- 【求和】题解
- 51nod 1081 子段求和
- 51nod-1225-余数求和(分块)
- 51nod-1081子段求和
- 51nod 1081 子段求和
- 51nod 1081 子段求和
- 瞬态变量
- [微信小程序]知识总结及案例汇总
- OKVIS 代码框架
- vivado与modelsim的联合仿真(二)
- android apk编译时间获取
- 51NOD 序列求和 V5题解
- python的制表工具包Matplotlib
- 不埋坑,不踩坑(软件设计篇)
- 推荐系统:技术、评估及高效算法 第3章
- PCA&ICA
- CSU 1803 a×b 是 2016 的倍数(枚举)
- 2016年第13周沸点例会 python wireshark
- MFC之IP控件(IP地址与CString的互相转化)
- cssCSS实用技巧18招