hdu1845(a^b的因子和%p)
题目链接:http://poj.org/problem?id=1845
思路:
1.整数唯一分解定理:
任意正整数都有且只有一种方式写出其素因子的乘积表达式。
a=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 其中pi均为素数
2.约数和公式:
对于已经分解的整数a=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)
有a的所有因子之和为
S` = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)
那么 a^b 的所有因子和为
S = (1+p1+p1^2+p1^3+...p1^(k1*b)) * (1+p2+p2^2+p2^3+….p2^(k2*b)) * (1+p3+ p3^3+…+ p3^(k3*b)) * .... * (1+pn+pn^2+pn^3+...pn^(kn*b))
对于数列 1, p, p^2, p^3 ... p^n % mod,其中 mod 为质数,打个表可以发现该数列是一个循环数列,其中存在一个循环节为 1, p, p^1, ... p^(mod-2).其实这点在费马小定理中是有体现的,a^(mod-1) = 1 (% mod).
那么对于求 cnt = 1 + p + p^2 + ... + p^n % mod,可以令
cc1 = (n + 1) / (mod - 1)
cc2 = (n + 1) % (mod - 1)
cnt1 = 1 + p + p^2 + ... + p^(mod - 2)
cnt2 = 1 + p + p^2 + ... + p^(cc2 - 1)
那么 cnt = cc1 * cnt1 + cnt2 % mod
对于求 a^b,可以先将 a 质因分解,得到 S 的表达式,对于 S 表达式,只需要按照上面的方法求出其中每个乘数项即可.时间复杂度为 O(loga * mod), 本题中 mod = 9901, 时间上是允许的.
代码:
- #include <iostream>
- #include <stdio.h>
- #include <map>
- #define ll long long
- using namespace std;
- const int mod = ;
- const int MAXN = 1e5 + ;
- ll prime[MAXN], indx = ;
- map<int, int> num;
- int get(ll a, ll b){//计算sigma(a^i),其中0<=i<=b
- ll sol1 = , sol2 = -, cnt = ;
- ll cc1 = (b + ) / (mod - );
- ll cc2 = (b + ) % (mod - );
- for(int i = ; i < mod - ; i++){
- sol1 = (sol1 + cnt) % mod;
- if(sol2 == - && i + == cc2) sol2 = sol1;
- cnt = (cnt * a) % mod;
- }
- return (sol1 * cc1 % mod + sol2) % mod;
- }
- int main(void){
- ll a, b, sol = ;
- cin >> a >> b;
- for(int i = ; i * i <= a; i++){
- if(a % i == ){
- prime[indx] = i;
- while(a % i == ){
- num[i]++;
- a /= i;
- }
- indx++;
- }
- }
- if(a > ) prime[indx++] = a, num[a]++;
- for(int i = ; i < indx; i++){
- sol = (sol * get(prime[i], b * num[prime[i]])) % mod;
- }
- cout << sol << endl;
- return ;
- }
但是当 mod 比较大时这个方法就不行了,mod 比较大时可以用下面这个代码,贴的 Kuangbin 模板
代码:
- #include <stdio.h>
- #include <math.h>
- #include <iostream>
- #include <algorithm>
- #include <string.h>
- #define ll long long
- using namespace std;
- //******************************************
- //素数筛选和合数分解
- const int MOD = ;
- const int MAXN=;
- int prime[MAXN+];
- void getPrime(void){
- memset(prime, , sizeof(prime));
- for(int i = ; i <= MAXN; i++)
- {
- if(!prime[i]) prime[++prime[]] = i;
- for(int j=; j<= prime[]&&prime[j] <= MAXN/i; j++)
- {
- prime[prime[j]*i] = ;
- if(i % prime[j] == ) break;
- }
- }
- }
- ll factor[][];
- int fatCnt;
- int getFactors(ll x){
- fatCnt = ;
- ll tmp = x;
- for(int i=; prime[i] <= tmp/prime[i]; i++){
- factor[fatCnt][] = ;
- if(tmp % prime[i] == ){
- factor[fatCnt][] = prime[i];
- while(tmp % prime[i] == ){
- factor[fatCnt][]++;
- tmp /= prime[i];
- }
- fatCnt++;
- }
- }
- if(tmp!=)
- {
- factor[fatCnt][]=tmp;
- factor[fatCnt++][]=;
- }
- return fatCnt;
- }
- //******************************************
- ll pow_m(ll a, ll n)//快速模幂运算
- {
- ll res = ;
- ll tmp = a % MOD;
- while(n){
- if(n & ){
- res *= tmp;
- res%=MOD;
- }
- n >>= ;
- tmp *= tmp;
- tmp %= MOD;
- }
- return res;
- }
- ll sum(ll p, ll n){//计算1+p+p^2+...+p^n
- if(p == )return ;
- if(n == )return ;
- if(n & ){//奇数
- return (( + pow_m(p, n/ + )) % MOD * sum(p, n / ) % MOD) % MOD;
- }else return (( + pow_m(p, n / + )) % MOD * sum(p, n / - ) + pow_m(p, n / ) % MOD) % MOD;
- }
- int main(void){
- int A, B;
- getPrime();
- while(scanf("%d%d", &A, &B) != EOF){
- getFactors(A);
- ll ans = ;
- for(int i = ; i < fatCnt; i++){
- ans *= (sum(factor[i][], B * factor[i][]) % MOD);
- ans %= MOD;
- }
- printf("%lld\n",ans);
- }
- return ;
- }
hdu1845(a^b的因子和%p)的更多相关文章
- Uva 11395 Sigma Function (因子和)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=109329#problem/C 题目在文末 题意:1~n (n:1~1012)中,因子 ...
- LightOj 1098 - A New Function(求1-n所有数的因子和)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1098 题意:给你一个数n (0 ≤ n ≤ 2 * 109),求n以内所有数的因子和, ...
- nylg 小M的因子和
小M的因子和 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 小M在上课时有些得意忘形,老师想出道题目难住他.小M听说是求因子和,还是非常得意,但是看完题目是求A的B ...
- 洛谷P1593 因子和
题目描述 输入两个正整数a和b,求a^b的因子和.结果太大,只要输出它对9901的余数. 输入输出格式 输入格式: 仅一行,为两个正整数a和b(0≤a,b≤50000000). 输出格式: a^b的因 ...
- 因子和(luoguP1593)(等比数列求和+逆元)
输入两个正整数\(a\)和\(b\),求\(a\cdot b\)的因子和.结果太大,只要输出它对9901的余数. Input 仅一行,为两个正整数\(a\)和\(b\)(\(0≤a,b≤5000000 ...
- [转]Laplace算子和Laplacian矩阵
1 Laplace算子的物理意义 Laplace算子的定义为梯度的散度. 在Cartesian坐标系下也可表示为: 或者,它是Hessian矩阵的迹: 以热传导方程为例,因为热流与温度的梯度成正比,那 ...
- 七夕节---hdu1215(打表求因子和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1215 给你一个数n(1<=n<=50w)求n的所有因子和, 由于n的范围比较大,所以要采用 ...
- 王子和公主 UVa10635
[题目描述]:王子和公主 一个王子和公主在n*n的格子中行走,这些格子是有1....n^2的编号的.现在给定p+1个数,再给定q+1个数,公主和王子可以选择其中某些格子行走,求他们最多能走几个相同的格 ...
- hdu-1452 Happy 2004---因子和+逆元
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1452 题目大意: 求2004^x次方的因子和mod29的值 解题思路: 首先2004 = 2 * 2 ...
随机推荐
- sleep 和 usleep的实现方法
一.sleep 和 usleep 1.不属于系统调用,是glibc 库函数实现的: 2.glibc函数库中通过调用内核的nanosleep实现的: 3.内核nanosleep通过调用 hrtimer_ ...
- FlatBuffers使用简介
@[tools|flatbuffers|opensource] 概述### Google在今年6月份发布了跨平台序列化工具FlatBuffers,提供了C++/Java/Go/C#接口支持,这是一个注 ...
- AngularJS:HTML DOM
ylbtech-AngularJS:HTML DOM 1.返回顶部 1. AngularJS HTML DOM AngularJS 为 HTML DOM 元素的属性提供了绑定应用数据的指令. ng-d ...
- springmvc----demo3---rest风格---bai
input_stu_path.jsp: showinput_stu_path.jsp:
- Winsock 传输文件
文件传输的原理:发送方把文件读到socket发送端缓冲区中,接收方把socket接收端缓端冲区中的数据写到一个新文件中.当然了,大文件需要循环读写! 服务器端为发送端: #include " ...
- 第九章 Java中线程池
Java中的线程池是运用场景最多的并发框架,几乎所有需求异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 降低资源消耗:通过重复利用已创建的线程降低线程创建和 ...
- java线程面试题及答案
1)2017Java面试题及答案:什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务 ...
- 11-16网页基础--HTML
网页制作部分主要讲解三大部分: 1.HTML 超文本标记语言( 全称:Hyper Text Markup Language) 专门编辑静态网页 2.CSS 网页美化:是HTML控制的 ...
- 问题:Oracle出发器;结果:1、Oracle触发器详解,2、Oracle触发器示例
ORACLE触发器详解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创 ...
- LAMP 3.0 mysql配置讲解
mysql 安装好后,我们是从安装包的 support-files 里面复制过来一个模板配置文件,默认 mysql 配置文件是在/etc/my.cnf 下,其实这个路径或者文件名字我们是可以修改的,在 ...