[数论+二分求等比数列]POJ 1845 Sumdiv
来源:互联网 发布:算法复杂性理论 编辑:程序博客网 时间:2024/06/11 21:03
题目链接 :http://poj.org/problem?id=1845
题目大意 :求A^B 所有因子的和% 9901
思路 :A = p1^a1 * p2^a2 * ... ... * pn^a3 那么A的所有因子之和为 sigma ( pi^0 + pi^1 + pi^2 + ... ... + pi^ai )
A^B 的所有因子之和为 sigma ( pi^0 + pi^1 + pi^2 + ... ... + pi^(ai*B ))
对于 ( pi^0 + pi^1 + pi^2 + ... ... + pi^(ai*B )) 这是一个等比数列,可以用二分求解,时间复杂度为logN
Code:
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>using namespace std;#define foru(i, a, b) for (int i=a; i<=b; i++)#define ford(i, a, b) for (int i=a; i>=b; i--)#define ll __int64#define M 9901#define N 10001bool f[N];int pri[N], m = 0 ;void getpri(){ foru(i, 2, N-1){ if (! f[i]) {m++; pri[m] = i;} foru(j, 1, m){ if (i * pri[j] > N-1) break; f[i * pri[j]] = 1; if (i % pri[j] == 0) break; } }}ll g(ll a, ll b){ ll s = 1; while (b){ if ((b&1) == 1) s = (s*a)%M; b >>= 1; a = (a*a)%M; } return s;}ll x, y;ll getsum(ll p, ll n){ if (! n) return 1ll; if (n&1) return (getsum(p, n/2) * (1 + g(p, n/2+1)))%M; return (getsum(p, n/2-1) * (1 + g(p, n/2+1)) + g(p, n/2))%M;}ll get(){ ll sum = 1ll; foru(i, 1, m){ if (x == 1) break; ll t = 0ll; while (x%pri[i] == 0){ t ++; x /= pri[i]; if (x == 1) break; } if (t == 0) continue; sum = (sum * getsum(pri[i], t*y))%M; } if (x > 1) sum = (sum * getsum(x, y))%M; while (sum < 0) sum += M; return sum;}int main(){ //freopen("K.txt", "r", stdin); getpri(); while (scanf("%I64d %I64d", &x, &y)!= EOF ){ if (! x && ! y) printf("%I64d\n", 1ll); else if (! x) printf("%I64d\n", 0ll); else if (! y)printf("%I64d\n", 1ll); else printf("%I64d\n", get()); } return 0;}
Tips:
二分求等比数列pi^0 + pi^1 + pi^2 + ... ... + pi^n
1°若n是偶数,那么等比数列一共有奇数项,(1 + pi^1 + pi^2 + ... ... + pi^(n/2-1)) * (1 +pi^(n/2+1) ) + pi^(n/2) 最高次 (n/2-1) +(n/2+1) = n, 加上中间漏掉的n/2项
2°若n是奇数,那么等比数列一共有偶数项,(1 + pi^1 + pi^2 + ... ... + pi^(n/2)) * (1 +pi^(n/2+1) ) 最高次 (n/2) +(n/2+1) = n
ll getsum(ll p, ll n){ if (! n) return 1ll; if (n&1) return (getsum(p, n/2) * (1 + g(p, n/2+1)))%M; return (getsum(p, n/2-1) * (1 + g(p, n/2+1)) + g(p, n/2))%M;}
0 0
- [数论+二分求等比数列]POJ 1845 Sumdiv
- poj 1845 Sumdiv(数论:欧拉函数+二分求等比数列前n项和+快速幂取模)
- POJ Sumdiv (数论+二分等比数列求和)
- poj 1845 Sumdiv(二分递归求等比数列+素因子分解)
- poj 1845 Sumdiv 数论--等比数列和(逆元或者递归)
- POJ 1845 Sumdiv(逆元或者二分求解等比数列)
- POJ1845 Sumdiv【因数之和】【二分求等比数列】
- poj 1845 Sumdiv 数论
- Sumdiv(数论综合模板题:快速分解因式+快速幂取模+约数和公式+递归二分求等比数列和)
- POJ 1845 Sumdiv <数论(逆元 / 二分递归)>
- POJ 1845 Sumdiv (逆元 等比数列求和)
- poj 1845Sumdiv(唯一分解定理&&约数和公式&&二分求等比数列和&&反复平方法计算p^n幂~~~好多定理啊)
- POJ 1845 Sumdiv(质因数分解+快速幂+二分法求等比数列的和)
- POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】
- POJ 1845 Sumdiv (唯一分解定理+求等比数列前n项和)
- POJ 1845 Sumdiv(数论)
- POJ 1845Sumdiv(数论)
- poj 1845 Sumdiv (数论)
- oracle 常用技能
- gvim 中编码问题
- android 浅谈消息处理机制
- Eclipse下编译C/C++程序出错:The program file specified in the launch configuration does not exist
- 路由器 集线器 交换机
- [数论+二分求等比数列]POJ 1845 Sumdiv
- Request.Form 和 Request.QueryString
- 50个Android开发技巧(01 好好利用layout_weight属性)
- 【机器学习算法-python实现】决策树-Decision tree(1) 信息熵划分数据集
- 简单工厂模式
- HBase-0.98.0和Phoenix-4.0.0分布式安装指南
- c4 Internet Address - Some useful Program
- C++第9周(春)项目5 - 一元一次方程类
- 连接数据库在JTable中显示