POJ 1845 Sumdiv(因子分解+快速幂+二分求和)
题意:给你A,B,让求A^B所有的因子和模上9901
思路:A可以拆成素因子的乘积: A = p1^x1 * p2^x2 *...* pn^xn
那么A^B = p1^(B*x1) * p2^(B*x2) *...* pn^(B*xn)
那么A^B所有的素因子和就是
(p1^0 + p1^1 + p1^2 + ... + p1^(B*x1) ) * (p2^0 + p2^1 + ... + p2^(B*x2) ) * ... * (pn^0 + pn^1 + ... + pn^(B*xn))
可以看出每一个括号内都是等比数列,但是不要用等比数列公式,因为有除法(刚开始我用除法,然后求了模的逆元,wa到爽死),因为不一定满足乘法逆元所需要的条件,除数与模数可能不互素(除数可能是模数的多少倍)。既然不能用公式,那么就要借助于二分了。比如如下式子求和:A1+A2+A3+A4 = A1+A2+A2(A1+A2)。通过这个式子发现,只要求出来A2就行了,然后只要计算一次A1+A2,就可以省掉一半的计算量。那么同理A1+A2也可以继续往下分。
现在推广到一般式。A1+A2+...+An
1) n为偶数: A1+A2+...+An = A1+A2+ ...+A(n/2)+ A(n/2)(A1+A2+...+A(n/2))
2) n为奇数: A1+A2+...+An = A1+A2+ ...+A(n/2)+ A(n/2)(A1+A2+...+A(n/2)) + An
推出来这些就可以递归求解了。
注:找素因子时,打个素数表,只需要打到sqrt(n)就行了,因为只可能在sqrt(n)里面,如果有比sqrt(n)大的两个素因子,乘积自然就大于n了,所以只需要sqrt(n)就可以了。因为就算有一个大素数和一个小素数相乘得来,那么在约掉小素数的时候,只剩大素数了,这会就直接跑到循坏外判断了。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
const int maxn = ;
const ll mod = 9901LL;
ll A, B;
struct Factor {
ll fac;
ll cnt;
}factor[maxn];
int tot;
bool prime[maxn + ];
int pr[maxn];//素数表
int pr_cnt;
void init_prime()
{
memset(prime, true, sizeof(prime));
prime[] = prime[] = false;
for (int i = ; i * i <= maxn; i++)
if (prime[i])
for (int j = i + i; j < maxn; j += i)
prime[j] = false;
pr_cnt = ;
for (int i = ; i <= maxn; i++)
if (prime[i])
pr[pr_cnt++] = i;
}
void init()//找到所有的素因子
{
tot = ;
memset(factor, , sizeof(factor));
for (int i = ; i < pr_cnt && pr[i] <= A; i++)
{
if (A % pr[i] == )
{
factor[tot].fac = pr[i];
while (A % pr[i] == )
{
factor[tot].cnt++;
A /= pr[i];
}
factor[tot].cnt *= B;
tot++;
}
}
if (A > )
{
factor[tot].fac = A;
factor[tot++].cnt = B;
}
}
ll quickpow(ll a, ll b, ll mod)
{
ll ans = 1LL;
while (b)
{
if (b & ) ans = ans * a % mod;
a = a * a % mod;
b >>= ;
}
return ans % mod;
}
ll binary_pow(ll a, ll b, ll mod)//计算等比数列的和
{
if (b == ) return 1LL;
if (b == ) return a;
ll ans = ;
if (b & )
{
ans = quickpow(a, b, mod);
ans = (ans + (quickpow(a, b / , mod) + 1LL) % mod * binary_pow(a, b / , mod)) % mod;
}
else
ans = (quickpow(a, b / , mod) + 1LL) % mod * binary_pow(a, b / , mod) % mod;
return ans;
}
void solve()
{
if (B == )
{
puts("");
return;
}
if (A == )
{
puts("");
return;
}
init();
ll ans = 1LL;
for (int i = ; i < tot; i++)
{
ans = ans * (binary_pow(factor[i].fac, factor[i].cnt, mod) + 1LL) % mod;
}
cout << ans << endl;
}
int main()
{
init_prime();
while (cin >> A >> B)
{
solve();
}
return ;
}
POJ 1845 Sumdiv(因子分解+快速幂+二分求和)的更多相关文章
- POJ 3233 Matrix Power Series 矩阵快速幂+二分求和
矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...
- poj 1845 POJ 1845 Sumdiv 数学模板
筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...
- POJ 1845 Sumdiv
快速幂+等比数列求和.... Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12599 Accepted: 305 ...
- POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]
传送门:http://poj.org/problem?id=1845 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有 ...
- POJ 1845 Sumdiv (整数拆分+等比快速求和)
当我们拆分完数据以后, A^B的所有约数之和为: sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...*[1+pn+pn^2 ...
- POJ 1845 Sumdiv 【二分 || 逆元】
任意门:http://poj.org/problem?id=1845. Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions ...
- POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)
题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...
- POJ 3233 矩阵快速幂&二分
题意: 给你一个n*n的矩阵 让你求S: 思路: 只知道矩阵快速幂 然后nlogn递推是会TLE的. 所以呢 要把那个n换成log 那这个怎么搞呢 二分! 当k为偶数时: 当k为奇数时: 就按照这么搞 ...
- POJ 1845 Sumdiv 【逆元】
题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和 用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...
随机推荐
- [wikioi]能量项链
http://wikioi.com/problem/1154/ 这是石子归并的加强版,基本就是分治法的DP.但是有了个环,因为任何一个位置都可开始,所以就建立2*N的数组,然后对可能的区间遍历一次,就 ...
- ANDROID_MARS学习笔记_S04_001_OAuth简介
一.OAuth简介
- 打造属于自己的Altium Designer 3D封装库,不需要懂专门的三维设计软件
看到Andy_2020发的帖子“Altium Designer专题”之后,对Altium Designer的3D功能很感兴趣,着手自己做一个AD的3D封装库.刚开始按照Andy介绍的方法,学了两天So ...
- Delphi组件indy 10中IdTCPServer修正及SSL使用心得
indy 10终于随着Delphi2005发布了,不过indy套件在我的印象中总是复杂并且BUG不断,说实话,不是看在他一整套组件的面子上,我还是喜欢VCL原生的Socket组件,简洁,清晰.Indy ...
- Qt的事件模型(5种使用办法,通常重新实现event handler即可。只有定义控件才需要管理信号的发射)
Qt的事件模型 1.事件的概念 应用程序对象将系统消息接收为 Qt 事件.应用程序可以按照不同的粒度对事件加以监控.过滤并做出响应. 在 Qt 中,事件是指从 QEvent继承 的对象.Qt将事件发送 ...
- HTML input标签的checked属性与Razor解析
在HTML中,input标签可以通过type属性设置为checkbox.同时,也就包含了一个checked属性.对于这个checked属性,有一个特别的地方就是,它可以不需要属性值就可以表示是否选择了 ...
- 转载:浅谈Java多线程的同步问题【很好我就留下来,多分共享】
转载:http://www.cnblogs.com/phinecos/archive/2010/03/13/1684877.html#undefined 多线程的同步依靠的是对象锁机制,synchro ...
- bzoj1034
贪心 尽可能让最强的赢,最弱的赢,都不行则最弱打最强 感性的想,我肯定要尽可能的赢,而且赢的要对等 实在不能赢就拿最小的拼,所谓的田忌赛马策略 由于总分一定,己方最差即己方最好时对方的分数 ..] o ...
- SPOJ_10628_Count_on_a_Tree_(主席树+Tarjan)
描述 http://www.spoj.com/problems/COT/ 给出一棵n个节点的树,树上每一个节点有权值.m次询问,求书上u,v路径中第k小的权值. COT - Count on a tr ...
- Ubuntu全新系统一些配置
0.安装JDK,http://www.oracle.com/technetwork/java/javase/downloads/index.html 1.安装Intellij IDEA,https:/ ...