poj3696 The Luckiest number By Assassin
2017-04-26 23:19
288 查看
本题真是一道好题,被坑了一晚上才做出来…
题目大意:给定一个数组L,求是否存在形如8888…888的数字可以被L整除。如果有求最短的。
一开始拿到题目真的是不知所以然…直到最后也是参考别人的思路,不过毕竟队伍中数学题的锅不是我背的~哈哈~用的是信息安全数学上面的知识,下面见分析。
1.8*(111…1111)=mL(其中m我们是不知道的,L是给定值,并且我们现在假设存在等式成立)
2.进一步变化可以得到 :
8*(10^k-1)/9=mL
8*(10^k-1)=9mL
3.假定d=gcd(8,L);定义p=8/d、q=9L/d,这个时候易得p和q互质这个时候式子的形式如下p*(10^k-1)=mq
4.因为p和q互质,那么一定有(10^k-1)%q==0,即10^k==1 modp
5.假设gcd(10,q)==1,根据欧拉函数可得一定存在10^phi(q)==1 mod p,当然如果gcd(10,q)!=1根本不存在上述情况,等式不成立,这个时候输出0
6.再次根据欧拉定理性质,虽然phi(q)可以是10的阶数,但是不一定是最小的!那么我们还要找更小的值!而且可能的答案一定是phi(q)的因数。
2.这里L实在是太大了,大到得到的q可能也很大,这个时候就存在long long乘法都爆炸的情况,所以乘法函数也得自己写 !凸(艹皿艹 )
3.在我们去phi(q)的人家有现成的公式啊
(1). 将n表示成素数的乘积: n = p1 ^ k1 * p2 ^ k2 * … * pn ^kn(这里p1, p2, …, pn是素数)
(2). PHI(n) = (p1 ^ k1 - p1 ^ (k1 - 1)) * (p2 ^ k2 - p2 ^ (k2 - 1)) * … * (pn ^ kn - pn ^ (kn - 1))
=n*(p1-1)(p2-1)……(pi-1)/(p1*p2*……pi);
=n*(1-1/p1)*(1-1/p2)….(1-1/pn)
题目大意:给定一个数组L,求是否存在形如8888…888的数字可以被L整除。如果有求最短的。
一开始拿到题目真的是不知所以然…直到最后也是参考别人的思路,不过毕竟队伍中数学题的锅不是我背的~哈哈~用的是信息安全数学上面的知识,下面见分析。
分析:
首先我们假设形如888888的数字可以拆分如下:1.8*(111…1111)=mL(其中m我们是不知道的,L是给定值,并且我们现在假设存在等式成立)
2.进一步变化可以得到 :
8*(10^k-1)/9=mL
8*(10^k-1)=9mL
3.假定d=gcd(8,L);定义p=8/d、q=9L/d,这个时候易得p和q互质这个时候式子的形式如下p*(10^k-1)=mq
4.因为p和q互质,那么一定有(10^k-1)%q==0,即10^k==1 modp
5.假设gcd(10,q)==1,根据欧拉函数可得一定存在10^phi(q)==1 mod p,当然如果gcd(10,q)!=1根本不存在上述情况,等式不成立,这个时候输出0
6.再次根据欧拉定理性质,虽然phi(q)可以是10的阶数,但是不一定是最小的!那么我们还要找更小的值!而且可能的答案一定是phi(q)的因数。
下面讲一下坑点:
1.首先是根本不知道数据规模会是什么样子,尤其是看着第六步多个素数组合数,用dfs真的没超时???也是谢天谢地了,让我写多少不太敢用2.这里L实在是太大了,大到得到的q可能也很大,这个时候就存在long long乘法都爆炸的情况,所以乘法函数也得自己写 !凸(艹皿艹 )
3.在我们去phi(q)的人家有现成的公式啊
(1). 将n表示成素数的乘积: n = p1 ^ k1 * p2 ^ k2 * … * pn ^kn(这里p1, p2, …, pn是素数)
(2). PHI(n) = (p1 ^ k1 - p1 ^ (k1 - 1)) * (p2 ^ k2 - p2 ^ (k2 - 1)) * … * (pn ^ kn - pn ^ (kn - 1))
=n*(p1-1)(p2-1)……(pi-1)/(p1*p2*……pi);
=n*(1-1/p1)*(1-1/p2)….(1-1/pn)
我的丑代码
#include<bits/stdc++.h> using namespace std; long long value[100050],times[100050],tnum,lll; //拆分素数的值,出现次数 long long d,p,q,phi; long long answer[10000],anspos; //求phi(q)因数的存储空间 long long multi(long long a,long long b,long long mod){ //自己写的乘法公式 long long result=0; while(b){ if(b&1) result+=a; if(result>=mod) result-=mod; a=a+a; if(a>=mod) a-=mod; b>>=1; } return result; } long long quickmod(long long a,long long b,long long m){ //快速幂取模的模板 long long ans = 1; while(b){ if(b&1) { ans = multi(ans,a,m); b--; } b/=2; a = multi(a,a,m); } return ans; } long long check(long long n,long long mod){ //检测是否满足最终的验证 if(quickmod(10,n,mod)==1) return 1; else return 0; } long long gcd(long long a,long long b){ if(a%b==0) return b; return gcd(b,a%b); } void apart(long long l){ //将大数拆成素数的乘积 tnum=1; for(long long i=2;i*i<=l;i++){ if(l%i==0){ value[tnum]=i; times[tnum]=1; l/=i; while(l%i==0){ times[tnum]++; l/=i; } tnum++; } } if(l>1){ value[tnum]=l; times[tnum]=1; tnum++; } } void dfs(long long v,int t){ //dfs(求phi的因数) if(t==tnum){ answer[++anspos]=v; return ; } dfs(v,t+1); for(int i=1;i<=times[t];i++){ v*=value[t]; dfs(v,t+1); } } long long getphi(long long n) //这里phi(q)是有公式的 { long long ans=1,i; for(i=2;i*i<=n;i++) { if(n%i==0) { n/=i; ans*=i-1; while(n%i==0) { n/=i;ans*=i; } } } if(n>1) ans*=n-1; return ans; } int main(){ //freopen("input.txt","r",stdin); int T=0; while(scanf("%lld",&lll)&&lll){ anspos=0; d=gcd(8,lll); p=8/d; q=9*lll/d; d=gcd(10,q); if(d!=1){ printf("Case %d: 0\n",++T); continue; } phi=getphi(q); apart(phi); dfs(1,1); sort(answer+1,answer+anspos+1); for(int i=1;i<=anspos;i++){ if(check(answer[i],q)){ printf("Case %d: %lld\n",++T,answer[i]); break; } } } return 0; }
相关文章推荐
- POJ3696:The Luckiest number(欧拉函数||求某数最小的满足题意的因子)
- 【POJ3696】The Luckiest Number-欧拉定理+快速幂
- POJ3696 The Luckiest number【欧拉函数】
- POJ3696:The Luckiest number (欧拉定理)
- [POJ3696]The Luckiest number(数论)
- How to arrange 10 digits so that the product of the some of them is equal to a number represented by the remaining digits
- The Number of Triangles Formed by Intersecting Diagonals of a Regular Polygon
- 哈尔滨理工大学软件学院ACM程序设计全国邀请赛(网络同步赛)L Lucky Number By Assassin 杀人的模拟题
- poj 3696 The Luckiest number(欧拉函数+快速幂取模)
- HDU 2462 The Luckiest number
- The Number of Triangles Formed by Intersecting Diagonals of a Regular Polygon
- POJ 3696 The Luckiest number 推理~~难
- The Luckiest number POJ - 3696 (欧拉函数)
- POJ 3696 The Luckiest number
- poj 3696 The Luckiest number
- [HDU2462] The Luckiest number [2008 Asia Hefei Regional Contest Online G]
- POJ3696 The Luckiest number
- hdu 2462 数学欧拉 The Luckiest number
- POJ 3696 The Luckiest number(欧拉定理妙妙妙)
- POJ - 3696 The Luckiest number(求阶)