poj3696:同余方程,欧拉定理
感觉很不错的数学题,可惜又是看了题解才做出来的
题目大意:给定一个数n,找到8888....(x个8)这样的数中,满足能整除n的最小的x,若永远无法整除n 则输出0
做了这个题和后面的poj3358给我的感觉是这种复杂的数学题一定要哦上手去写,光想永远是想不出来的= =
做法:
基于欧拉定理:若gcd(a,m)=1 ,则满足 a^φ(m) mod m=1, 即 a-1=k*m
88888(x个8)可以表示为 (10^x-1)/9*8,整除n
于是可以设 (10^x-1)/9*8=n*k ,移项得到 10^x-1=k*n*9/8
一看,刚好满足 a-1=k*m的形式,由于 n*9/8不一定为整数,所以我们令 m=n*9/gcd(n,8) 替代一个k=k*gcd(n,8)/8当作未知数
所以得到同余方程 10^x mod m=1
首先判断是否有解
由于 a mod m=gcd(a,m)的倍数 当gcd(10,m)>1时,显然无解,反之 则有解。
由欧拉定理只 φ(m)为此方程的一个解,但不一定是最小解
由于mod 乘法是有循环节的,由于 10^0 mod m=1成立 即对0,和φ(m)都成立,所以循环节要么是φ(m),要么是φ(m)的约数
所以我们只需要对φ(m)进行素因子分解,判断是否满足同余方程,就可以找到最小的解
代码:
#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define I64d lld
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
long long fac[];
long long nfac;
long long phi(long long n)
{
long long res=n;
for(long long i=;i*i<=n;i++)
{
if(n%i==)
{
res=res-res/i;
while(n%i==)
n/=i;
}
}
if(n>)
res=res-res/n; //可能还有大于sqrt(n)的素因子
return res; }
long long random(long long n)
{
return (long long)(rand()%(n-)+);
}
long long multi(long long a,long long b,long long m)//a*b%m
{
long long res=;
while(b>)
{
if(b&)
res=(res+a)%m;
b>>=;
a=(a<<)%m;
}
return res;
}
long long quickmod(long long a,long long b,long long m) //a^b%m
{
long long res=;
while(b>)
{
if(b&)
res=multi(res,a,m);
b>>=;
a=multi(a,a,m);
}
return res;
}
int check(long long a,long long n,long long x,long long t)
{
long long res=quickmod(a,x,n);
long long last=res;
for(int i=;i<=t;i++)
{
res=multi(res,res,n);
if(res==&&last!=&&last!=n-) return ;
last=res;
}
if(res!=) return ;
return ;
} int primetest(long long n)
{
if(n<)return ;
if(n==)return ;
if((n&)==) return ;
long long x=n-;
long long t=;
while((x&)==){x>>=;t++;}
for(int i=;i<;i++)
{
long long a=random(n);
if(check(a,n,x,t))
return ;
}
return ;
} long long pollardrho(long long n,long long c)
{
long long x,y,d,i,k;
i=;k=;
x=random(n);
y=x;
while()
{
i++;
x=(multi(x,x,n)+c)%n;
long long tmp=y-x>=?y-x:x-y;
d=gcd(tmp,n);
if(d>&&d<n)
return d;
if(y==x)
return n;
if(i==k)
{
y=x;
k+=k;
}
}
}
void findfac(long long n)
{
if(n==)
return;
if(primetest(n))
{
fac[nfac++]=n;
return;
}
long long p=n;
while(p>=n)
p=pollardrho(n,random(n-));
findfac(p);
findfac(n/p);
}
int main()
{
long long n,m;
int cas=;
while(scanf("%I64d",&n),n)
{
cas++;
m=n*/gcd(n,);
if(gcd(m,)!=)
{
printf("Case %d: %d\n",cas,);
continue;
}
long long p=phi(m);
nfac=;
findfac(p);
for(int i=;i<nfac;i++)
{
p/=fac[i];
if(quickmod(,p,m)!=)
p*=fac[i]; }
printf("Case %d: %I64d\n",cas,p);
} return ;
}
poj3696:同余方程,欧拉定理的更多相关文章
- POJ3696 The Luckiest Number 欧拉定理
昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...
- POJ3696【欧拉函数+欧拉定理】
题意: 求最小T,满足L的倍数且都由8组成,求长度: 思路: 很强势的福利:点 图片拿出去食用更优 //#include<bits/stdc++.h> #include<cstdio ...
- 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)
什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...
- poj3358:欧拉定理
又是一道用欧拉定理解的题..嗯,关键还是要建好方程,注意一些化简技巧 题目大意: 给定一个由 p / q 生成的循环小数,求此循环小数在二进制表示下的最小循环节以及不是循环节的前缀 思路: 小数化为二 ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
- 数论入门2——gcd,lcm,exGCD,欧拉定理,乘法逆元,(ex)CRT,(ex)BSGS,(ex)Lucas,原根,Miller-Rabin,Pollard-Rho
数论入门2 另一种类型的数论... GCD,LCM 定义\(gcd(a,b)\)为a和b的最大公约数,\(lcm(a,b)\)为a和b的最小公倍数,则有: 将a和b分解质因数为\(a=p1^{a1}p ...
- POJ_3696 The Luckiest number 【欧拉定理+同余式+对取模的理解】
一.题目 Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his ...
- COGS——T 1265. [NOIP2012] 同余方程
http://cogs.pro/cogs/problem/problem.php?pid=1265 ★☆ 输入文件:mod.in 输出文件:mod.out 简单对比时间限制:1 s 内 ...
- 高次同余方程 $BSGS$
第一篇\(Blog\)... 还是决定把\(luogu\)上的那篇搬过来了. BSGS,又名北上广深 它可以用来求\(a^x \equiv b (mod \ n)\)这个同余方程的一个解,其中\(a, ...
随机推荐
- 关于UIView 的autoresizingMask属性,即UIViewAutoresizing
enum { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 &l ...
- Jmeter数据库连接
1.添加配置元件:测试计划右键-->配置元件-->JDBC Connection Configuration如下图: 注意:上述的Variable Name:在后续的JDBC Reques ...
- 你需要知道的九大排序算法【Python实现】源码
#coding: utf-8 #!/usr/bin/python import randomimport math #随机生成0~100之间的数值def get_andomNumber(num): l ...
- 【C#多线程】C#多线程 Thread 开发基础
引用 using System; using System.Threading; 多线程代码 Thread mainthread = new Thread(ExecuteThread); mainth ...
- [React] React Router: Router, Route, and Link
In this lesson we'll take our first look at the most common components available to us in react-rout ...
- java中不常见的keyword:strictfp,transient
1.strictfp, 即 strict float point (精确浮点). strictfp keyword可应用于类.接口或方法.使用 strictfp keyword声明一个方法时,该方法中 ...
- Java基础知识强化32:String类之String类的判断功能
1. String类的判断功能: boolean equals (Object obj ) boolean equalsIgnoreCase (String str ) boolean contain ...
- Linux中的小程序—— 进度条
在说正事之前,首先科普一下在什么是回车什么是换行? 我们通常所说的回车就是从一行的末尾跳到另一行的开头,但事实上这却是由回车和换行两个动作所完成的,也就是键盘上<enter>所完成的工作. ...
- u盘启动盘制作工具
u盘启动盘制作工具http://www.dabaicai.biz/ 系统镜像文件下载:http://xt.qingdiangongsi.cn/xtxz/
- 浅谈MDX处理空值NULL及格式化结果
MDX查询结果中往往会含有"NULL"值,这是某维度下对应的的量值不存在导致的,为了让报表呈现更好的效果,在有些情况下,需要将"NULL"的切片值置换成0,这些 ...