题目链接: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)的更多相关文章

  1. Uva 11395 Sigma Function (因子和)

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=109329#problem/C   题目在文末 题意:1~n (n:1~1012)中,因子 ...

  2. LightOj 1098 - A New Function(求1-n所有数的因子和)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1098 题意:给你一个数n (0 ≤ n ≤ 2 * 109),求n以内所有数的因子和, ...

  3. nylg 小M的因子和

    小M的因子和 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 小M在上课时有些得意忘形,老师想出道题目难住他.小M听说是求因子和,还是非常得意,但是看完题目是求A的B ...

  4. 洛谷P1593 因子和

    题目描述 输入两个正整数a和b,求a^b的因子和.结果太大,只要输出它对9901的余数. 输入输出格式 输入格式: 仅一行,为两个正整数a和b(0≤a,b≤50000000). 输出格式: a^b的因 ...

  5. 因子和(luoguP1593)(等比数列求和+逆元)

    输入两个正整数\(a\)和\(b\),求\(a\cdot b\)的因子和.结果太大,只要输出它对9901的余数. Input 仅一行,为两个正整数\(a\)和\(b\)(\(0≤a,b≤5000000 ...

  6. [转]Laplace算子和Laplacian矩阵

    1 Laplace算子的物理意义 Laplace算子的定义为梯度的散度. 在Cartesian坐标系下也可表示为: 或者,它是Hessian矩阵的迹: 以热传导方程为例,因为热流与温度的梯度成正比,那 ...

  7. 七夕节---hdu1215(打表求因子和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1215 给你一个数n(1<=n<=50w)求n的所有因子和, 由于n的范围比较大,所以要采用 ...

  8. 王子和公主 UVa10635

    [题目描述]:王子和公主 一个王子和公主在n*n的格子中行走,这些格子是有1....n^2的编号的.现在给定p+1个数,再给定q+1个数,公主和王子可以选择其中某些格子行走,求他们最多能走几个相同的格 ...

  9. hdu-1452 Happy 2004---因子和+逆元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1452 题目大意: 求2004^x次方的因子和mod29的值 解题思路: 首先2004 = 2 * 2 ...

随机推荐

  1. hihoCoder1296:约瑟夫问题

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho的班级正在进行班长的选举,他们决定通过一种特殊的方式来选择班长. 首先N个候选人围成一个圈,依次编号为0.. ...

  2. 线程及同步的性能 – 线程池/ ThreadPoolExecutors/ ForkJoinPool

    线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...

  3. java数组复制的几种常见用法

    1.1数组复制的几种常见用法 1.1.1System.arraycopy的用法 int[] src = {1,3,5,7,9,11,13,15,17}; int[] dest = {2,4,6,8,1 ...

  4. 西安电子科技大学第16届程序设计竞赛 F Operating System (unique() 去重函数)

    链接:https://www.nowcoder.com/acm/contest/107/F来源:牛客网 Operating System 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ ...

  5. python第二十三天-----Tornado

    Tornado是一个轻量级完整的web框架,在Linux系统下它会使用epoll,是一个异步非阻塞的web服务器框架,对于实时应用来说很理想,想想同是异步非阻塞的nginx的残暴程度就知道了 1.路由 ...

  6. Oracle RMAN 学习:演练进阶篇

    Oracle RMAN 学习:演练进阶篇 5 Rman备份演练进阶篇 5.1 是否选择增量备份 Backup命令生成的备份集中只备份了那些使用了的数据块,备份集实际大小已经较目标数据库的数据文件小了很 ...

  7. Ubuntu16.04+TensorFlow r1.12环境搭建指南

    一.操作系统安装 OS版本:Ubuntu 16.04 (ubuntu-16.04.5-server-amd64.iso) CPU:4Core以上 内存:4GB以上 磁盘空间:80G以上 二.基础环境准 ...

  8. elasticsearch配置文件里的一些坑 [Failed to load settings from [elasticsearch.yml]]

    这里整理几个空格引起的问题. 版本是elasticsearch-2.3.0 或者elasticsearch-rtf-master Exception in thread "main" ...

  9. HTML5的头部、拨号、短信、邮件(转)

    HTML5[语法要点] 一.头部设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!--页面窗口自动调整到设备 ...

  10. Codeforces 914C Travelling Salesman and Special Numbers (数位DP)

    题意:题目中定义了一种运算,把数字x变成数字x的二进制位数.问小于n的恰好k次运算可以变成1的数的个数(题目中的n是二进制数,n最大到2^1000) 思路:容易发现,无论多么大的数,只要进行了一次运算 ...