poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】
题意不说了,网上一大堆。此题做了一天,必须要整理一下了。

刚开始用费马小定理做,WA。(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然就是0了,需要特判一下,但是poj好像没有为0的数据,能AC。先不改了。)
后来看了好多人的博客,发现很少用费马小定理写的,或者写的代码我看不下去。。就先用那个什么二分等比数列写了一下。
过程也不说了,很多博客都说了。(【1】【2】):
#include<iostream>
#include<cmath>
#define mod 9901
using namespace std;
typedef long long ll;
const int maxn=;
ll p[maxn],r[maxn];
int tot; void Factor(ll n)//质因数分解
{
tot=;
int m=sqrt(n+0.5);
for (int i=;i<=m;i++)
if (n%i==){
p[++tot]=i;
r[tot]=;
while(n%i==){
++r[tot];
n/=i;
}
}
if(n>){
p[++tot]=n;
r[tot]=;
}
} ll qpow(ll a,ll b)//快速幂
{
ll r=;
while(b)
{
if(b&) r=r*a%mod;
b>>=;
a=a*a%mod;
}
return r;
} ll sum(int p,int n)//二分等比数列
{
if(n==)
return ;
if(n&)
return (sum(p,n/)%mod*(+qpow(p,n/+))%mod)%mod;
else
return (sum(p,n/-)%mod*(+qpow(p,n/+))%mod+qpow(p,n/))%mod;
} int main()
{
ll A,B;
cin>>A>>B;
Factor(A);
ll ans=;
for (int i=;i<=tot;i++)
{
ans=(ans%mod*sum(p[i],r[i]*B)%mod)%mod;
}
cout<<ans<<endl;
return ;
}
后来,又看见有人用二分乘法写:
#include<iostream>
#include<cmath>
#define mod 9901
using namespace std;
typedef long long ll;
const int maxn = ;
ll p[maxn], r[maxn];
int tot; void Factor(ll n)
{
tot = ;
int m = sqrt(n + 0.5);
for (int i = ; i <= m; i++)
if (n%i == ) {
p[++tot] = i;
r[tot] = ;
while (n%i == ) {
++r[tot];
n /= i;
}
}
if (n>) {
p[++tot] = n;
r[tot] = ;
}
} ll muti(ll a, ll b, ll m)//二分乘法???求教!!!
{
ll ans = ;
a %= m;
while (b)
{
if (b & )
{
ans = (ans + a) % m;
b--;
}
b >>= ;
a = (a + a) % m;
}
return ans;
} ll qpow(ll a, ll b, ll m)
{
ll ans = ;
a %= m;
while (b)
{
if (b & ) {
ans = muti(ans, a, m);
b--;
}
b >>= ;
a = muti(a, a, m);
}
return ans;
} int main()
{
ll A, B;
cin >> A >> B; Factor(A);
ll ans = ;
for (int i = ; i <= tot; i++)
{
ll m = (p[i] - )*mod;
ans *= (qpow(p[i], r[i] * B + , m) - + m) / (p[i] - );
ans %= mod;
}
cout << ans << endl;
return ;
}
说实话我现在还不懂为什么要二分乘法?啥子是二分乘法?这是ACdreamer(【1】)(应该是个大牛吧!!!)里面写的,后来也到过其他博客写过,代码都极其相似。ACdreamer说mb会可能会超int范围,所以快速幂时二分乘法。???我现在也很懵逼,mb超int怎么了?不超long long不就行了?难道超int模会出错?求解释啊!!!
后来,又看到了有人用拓展欧几里得:
#include<iostream>
#include<cmath>
#define mod 9901
using namespace std;
typedef long long ll;
const int maxn=;
ll p[maxn],r[maxn];
int tot; void Factor(ll n)
{
tot=;
int m=sqrt(n+0.5);
for (int i=;i<=m;i++)
if (n%i==){
p[++tot]=i;
r[tot]=;
while(n%i==){
++r[tot];
n/=i;
}
}
if(n>){
p[++tot]=n;
r[tot]=;
}
} ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==){
x=,y=;
return a;
}
int ret=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return ret;
} ll inv(ll n)
{
n%=mod;
ll a=n,b=mod,x,y;
exgcd(a,b,x,y);
x=(x%mod+mod)%mod;
return x;
} ll qpow(ll a,ll b)
{
ll r=;
while(b)
{
if(b&) r=a*r%mod;
b>>=;
a=a*a%mod;
}
return r;
} int main()
{
ll A,B;
cin>>A>>B; Factor(A);
ll ans=;
for (int i=;i<=tot;i++)
{
if(p[i]%mod==){//!!!
ans*=(r[i]*B+)%mod;
ans%=mod;
}else{
ans*=((qpow(p[i],r[i]*B+)-+mod)%mod*inv(p[i]-))%mod;
ans%=mod;
}
}
cout<<ans<<endl;
return ;
}
能拓展欧几里得那么费马小定理也应该差不多啊!!!
所以回头我又写了费马小定理的:
#include<iostream>
#include<cmath>
#define mod 9901
using namespace std;
typedef long long ll;
const int maxn=;
ll p[maxn],r[maxn];
int tot; void Factor(ll n)
{
tot=;
int m=sqrt(n+0.5);
for (int i=;i<=m;i++)
if (n%i==){
p[++tot]=i;
r[tot]=;
while(n%i==){
++r[tot];
n/=i;
}
}
if(n>){
p[++tot]=n;
r[tot]=;
}
} ll qpow(ll a,ll b)
{
ll r=;
a%=mod;
while(b)
{
if(b&) r=a*r%mod;
b>>=;
a=a*a%mod;
}
return r;
} int main()
{
ll A,B;
cin>>A>>B; Factor(A);
ll ans=;
for (int i=;i<=tot;i++)
{ if(p[i]%mod==){//!!!
ans*=(r[i]*B+)%mod;
ans%=mod;
}else{
ans*=((qpow(p[i],r[i]*B+)-+mod)%mod*qpow(p[i]-,mod-)%mod)%mod;//直接用费马小定理求逆元,qpow(p[i]-1,mod-2);
ans%=mod;
}
}
cout<<ans<<endl;
return ;
}
直到这时,我才明白我以前写费马为什么错了。因为当素因子p[i]%mod==1时,求逆元的结果是错的,或者就像有的博客说这时是求不出逆元的。因为这时qpow(p[i]-1,mod-2)的结果一定为0。因为当求(1+p^1+p^2+p^3...+p^r)%mod时,由于p%mod==1,所以每项%mod都是1,结果就是r+1。也就是上面两个代码特判的结果:r[i]*B+1。
最后提供一个数据: 59407 3
我的结果是:4
没有特判的话,结果会是0。这个就是我找到的第一个大于9901且%9901=1的质数。
感谢网上的广大博客,终于让我看了一天后悟出了这一点。。。。。
本来想巩固一下逆元的概念,结果ACdreamer里面看到的这道题弄了一天。。。
希望以后能看到这个文章的朋友们能够给我解释一下为什么要二分乘法?不理解啊!先谢谢!!
谢谢这些博客们,有可能没有一一列出,你们至多至少都给了我一点启发和帮助!也希望你们写博客的时候在关键能多说几句>_<.
【1】http://blog.csdn.net/acdreamers/article/details/8220787
【2】http://blog.csdn.net/lyy289065406/article/details/6648539
【3】http://blog.csdn.net/a601025382s/article/details/12233213
【4】http://blog.csdn.net/hlmfjkqaz/article/details/9735143
【5】http://www.cnblogs.com/mjy0724/p/4371752.html
【6】http://m.blog.csdn.net/kbdwo/article/details/9798193
【7】http://www.cnblogs.com/linyujun/p/5194184.html
poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】的更多相关文章
- UVA10200-Prime Time/HDU2161-Primes,例题讲解,牛逼的费马小定理和欧拉函数判素数。
10200 - Prime Time 此题极坑(本菜太弱),鉴定完毕,9遍过. 题意:很简单的求一个区间 ...
- 【bzoj5118】Fib数列2 费马小定理+矩阵乘法
题目描述 Fib定义为Fib(0)=0,Fib(1)=1,对于n≥2,Fib(n)=Fib(n-1)+Fib(n-2) 现给出N,求Fib(2^n). 输入 本题有多组数据.第一行一个整数T,表示数据 ...
- 【BZOJ】3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛(排列组合+乘法逆元+欧拉定理/费马小定理)
http://www.lydsy.com/JudgeOnline/problem.php?id=3398 以下牡牛为a,牝牛为b. 学完排列计数后试着来写这题,“至少”一词可以给我们提示,我们可以枚举 ...
- CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+高速幂)
C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 简记乘法逆元(费马小定理+扩展Euclid)
乘法逆元 什么是乘法逆元? 若整数 \(b,m\) 互质,并且\(b|a\) ,则存在一个整数\(x\) ,使得 \(\frac{a}{b}\equiv ax\mod m\) . 称\(x\) 是\( ...
- BZOJ_[HNOI2008]_Cards_(置换+Burnside引理+乘法逆元+费马小定理+快速幂)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1004 共n个卡片,染成r,b,g三种颜色,每种颜色的个数有规定.给出一些置换,可以由置换得到的 ...
- hdu1576-A/B-(同余定理+乘法逆元+费马小定理+快速幂)
A/B Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU 3923 Invoker(polya定理+乘法逆元(扩展欧几里德+费马小定理))
Invoker Time Limit : 2000/1000ms (Java/Other) Memory Limit : 122768/62768K (Java/Other) Total Subm ...
- hihocoder #1698 假期计划 (排列组合+费马小定理+乘法逆元)
Description 小Ho未来有一个为期N天的假期,他计划在假期中看A部电影,刷B道编程题.为了劳逸结合,他决定先拿出若干天看电影,再拿出若干天刷题,最后再留若干天看电影.(若干代指大于0) 每 ...
随机推荐
- Leetcode264. Ugly Number II丑数2
编写一个程序,找出第 n 个丑数. 丑数就是只包含质因数 2, 3, 5 的正整数. 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 ...
- jdbc原始连接
public class JdbcInstrt { public static void main(String[] args) { Connection conn = null; PreparedS ...
- fidder下载及使用
fidder 下载地址:https://www.telerik.com/download/fiddler 安装采用默认方式安装即可.
- poj 2115 扩展欧几里德
#include<stdio.h> #include<string.h> #define max 32 typedef long long LL; LL pow2[max+]; ...
- MyBatis Oracle批量插入
1.oracle如何insert into 多个values https://www.cnblogs.com/mq0036/p/6370224.html?utm_source=itdadao& ...
- Leetcode643.Maximum Average Subarray I子数组的最大平均数1
给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例 1: 输入: [1,12,-5,-6,50,3], k = 4 输出: 12.75 解释: 最大平均数 (12- ...
- JSP Web第八章整理复习 过滤器
P269 Filter过滤器的基本原理 P269 Filter过滤器体系结构 原理和体系结构看懂了就行 P270 例8-1过滤器代码与配置文件 略
- goland的下载安装破解并配置
1.下载地址:https://www.jetbrains.com/go/ 2.安装:简单 3.破解:https://www.cnblogs.com/igoodful/p/9113946.html 4. ...
- 想要快速完成一个Python项目,离不开这些开源库
链接:https://opensource.com/article/18/9/python-libraries-side-projects 在Python / Django世界中有一句话:我们为语言而 ...
- $(window).scrollTop() == $(document).height() - $(window).height()(底端)
jQuery(window).height()代表了当前可见区域的大小,而jQuery(document).height()则代表了整个文档的高度,可视具体情况使用. 注意当浏览器窗口大小改变时(如最 ...