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, ...
随机推荐
- zoj3658 Simple Function (函数值域)
Simple Function Time Limit: 2 Seconds Memory Limit: 32768 KB Knowing that x can be any real nu ...
- (转) xcodebuild和xcrun自动化编译ipa包 笔记
转自:http://blog.csdn.net/totogo2010/article/details/8883100 打包过程 xcodebuild负责将工程源文件编译成xxx.app xcrun负责 ...
- java.util.Map.Entry接口
java.util.Map.Entry接口主要就是在遍历map的时候用到,给你个例子:package test;import java.util.*;import java.util.Map.Entr ...
- 设计模式(3)-对象创建型模式-Abstract Factory模式
1.对象创建型模式 1.3 Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: • 一个系统要独立于它的产品的创建. ...
- Movie播放Gif,完美实现屏幕适配
android播放gif 我研究过3种 第一 :GifView支持android播放gif,效果是 先加载第一帧,然后慢慢加载完其他的针,这样效果视觉很不好,是从模糊到清晰的过程:第二:是流行的把g ...
- mybati之运行过程
mybatis其实就只有两个配置文件(mybatis-config.xml与mapper.xml) mybatis-config.xml配置基本的数据,和数据源,全局参数 mapper.xml 多个s ...
- LINQ更新用户
public Boolean UpdateUser(int id, string userName, string account, string password, string EkeyID, ...
- Polygon对象
Polylgon对象是由一个或多个Ring对象的有序集合,它可以是由单个Ring 对象构成,也可以使用多个Ring组成.Polygon通常用来代表有面积的多边形矢量对象,如行政区,建筑物等.
- java比较器Comparator 使用
PresonDemo package cn.stat.p5.person.demo; public class PresonDemo implements Comparable { private S ...
- 读书笔记_Effective_C++_条款十七:以独立语句将new产生的对象置入智能指针
int get_int(); void f(shared_ptr<int> a, int); //下面调用 f(new int(3), get_int());//如果是类而不是int就可以 ...