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 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】的更多相关文章

  1. UVA10200-Prime Time/HDU2161-Primes,例题讲解,牛逼的费马小定理和欧拉函数判素数。

                                                    10200 - Prime Time 此题极坑(本菜太弱),鉴定完毕,9遍过. 题意:很简单的求一个区间 ...

  2. 【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,表示数据 ...

  3. 【BZOJ】3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛(排列组合+乘法逆元+欧拉定理/费马小定理)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3398 以下牡牛为a,牝牛为b. 学完排列计数后试着来写这题,“至少”一词可以给我们提示,我们可以枚举 ...

  4. CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+高速幂)

    C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  5. 简记乘法逆元(费马小定理+扩展Euclid)

    乘法逆元 什么是乘法逆元? 若整数 \(b,m\) 互质,并且\(b|a\) ,则存在一个整数\(x\) ,使得 \(\frac{a}{b}\equiv ax\mod m\) . 称\(x\) 是\( ...

  6. BZOJ_[HNOI2008]_Cards_(置换+Burnside引理+乘法逆元+费马小定理+快速幂)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1004 共n个卡片,染成r,b,g三种颜色,每种颜色的个数有规定.给出一些置换,可以由置换得到的 ...

  7. hdu1576-A/B-(同余定理+乘法逆元+费马小定理+快速幂)

    A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  8. HDU 3923 Invoker(polya定理+乘法逆元(扩展欧几里德+费马小定理))

    Invoker Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 122768/62768K (Java/Other) Total Subm ...

  9. hihocoder #1698 假期计划 (排列组合+费马小定理+乘法逆元)

    Description 小Ho未来有一个为期N天的假期,他计划在假期中看A部电影,刷B道编程题.为了劳逸结合,他决定先拿出若干天看电影,再拿出若干天刷题,最后再留若干天看电影.(若干代指大于0)  每 ...

随机推荐

  1. 【python之路35】网络编程之socket相关

    Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  2. geoserver与OpenLayers配置

          geoserver与OpenLayers配置         目录   1     准备工作.... 4 1.1      需要用到的程序和资料... 4 2     地图格式转换方式(一 ...

  3. Cesium 1.50重量级新功能测评

    概要 既Cesium 1.49中3dtile加载性能大幅提升以后,Cesium 1.50再次迎来几个重量级新功能: 1 地球裁切,这下相当于可以截取一部分地形影像数据,当作一个平面场景来用了! 2 射 ...

  4. MYSQL基础常识

    所有的数据库名.表名.表字段都是区分大小写的.所以在使用mysql命令时需要输入正确的名称 MYSQL命令终止符是分号; 1.MYSQL的连接:mysql -u root -p(\q或exit退出); ...

  5. Angular js 具体应用(一)

    1,首先引用Angular  百度静态资源库搜索Angular  复制链接,在HTML中嵌入script 最好写在正文下面 <script type="text/javascript& ...

  6. notepad++ 退出后关闭所有文档(关闭“记住最后打开的文件”)

    旧版本: 设置->首选项->其他->取消勾选Remember current session for next launch 新版本: 设置->首选项->备份->取 ...

  7. 转: CentOS上安装LAMP之第一步:Apache环境及安装过程报错解决方案(纯净系统环境)

    传送门:http://blog.csdn.net/zhangatle/article/details/77416996  小心坑!填完就懂怎么安装了 Note:要从零开始搭建,就不要嫌中间遇到各种问题 ...

  8. pycharm 测试执行成功,但却无法成功生成测试报告(使用HTMLTestRunner)的解决办法

    pycharm 测试执行成功,在对应的测试路径下确未生成测试报告.反复确认代码也是没有问题的,在网上查找了原因:简单的unittest运行是不执行main方法的.是允许方式问题. 于是在mian方法里 ...

  9. 三、Redis操作

    一.基本介绍 1.简介 Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Remote Dictionary Ser ...

  10. JavaScript 防抖和节流

    1. 概述 1.1 说明 在项目过程中,经常会遇到一个按钮被多次点击并且多次调用对应处理函数的问题,而往往我们只需去调用一次处理函数即可.有时也会遇到需要在某一规则内有规律的去触发对应的处理函数,所以 ...