CH the luckiest number 欧拉函数 同余

解法

幸运数可以表示为(10^x-1)8/9,
所以 L | (10^x-1)
8/9,
所以 L9/d | (10^x-1) (d=gcd(L,8));
所以 1$\equiv$10^x (mod L
9/d)

可以通过反证法证明 若a^x$\equiv$1(mod n) 则 x是$\varphi$的约数;

所以只用从小到大枚举L*9/d的约数,用快速幂check即可。

错误代码

#include<bits/stdc++.h>
#define i8 __int128
using namespace std;
typedef long long LL;

LL L,phi,a[500000];

LL gcd(LL a,LL b)
{
	if(b==0) return a;
	return gcd(b,a%b);
}

LL Getphi(LL L)
{
	LL phi=L;
	for(int i=2;i*i<=L;i++)
	{
		if(L%i==0)
		{
			phi=phi/i*(i-1);
			while(L%i==0) L/=i;
		}
	}
	if(L>1) phi=phi/L*(L-1);
	return phi;
}

LL ksm(LL a,LL b,LL p)
{
	LL ans=1;
	while(b)
	{
		if(b&1) ans=(i8)ans*a%p;
		a=(i8)a*a%p;
		b>>=1;
	}
	return ans;
}

int main()
{
	int k=0;
	while(scanf("%lld",&L)==1 && L)
	{
		int op=0,m=0;
		printf("Case %d:",++k);
		
		L=L*9/gcd(L,8); 
		phi=Getphi(L);cout<<L<<" "<<phi<<endl;
	
		if(gcd(10,L)==1)
		{	
			for(int i=1;i*i<=phi;i++)
			{
				if(phi%i==0) a[++m]=i;
				if(i*i!=phi) a[++m]=i;
			}
			sort(a+1,a+m+1);
			for(int i=1;i<=m;i++)
				if(ksm(10,a[i],L)==1)
				{ printf("%lld\n",a[i]); break; }			
		}
		else printf("0\n");
	}
	return 0;
}

用__int128疯狂T和RE,不知道为什么。。
正解用的都是些玄学乘法,什么long double,还有lyd在第一章介绍的。。。
不想写了。

posted @ 2019-03-17 14:56  小蒟蒻lzq  阅读(103)  评论(0)    收藏  举报