POJ 3696

这里面的一个转换的小技巧很重要,把888...8转换成(10^x-1)/9*8。神来之笔,佩服。

这样有(10^x-1)/9*8=L*p得10^x-1=L*p*9/8,设m=9*L/gcd(L,8)。这一步如何想到的呢?其实是为了使m与10互质而做的。因为这样必有m*p1=10^x-1。使得同余方程

10^x=1 mod m,相信到了这一步,都知道用欧拉定理了。于是只需求出phi(m),枚举其因子,使得同余方程成立即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define LL __int64
using namespace std;

LL gcd(LL a,LL b){
	if(b==0) return a;
	return gcd(b,a%b);
}
LL fac[10000]; int cnt;
LL Euler(LL m){
	LL res=m;
	LL k=(LL)sqrt((double)m);
	for(LL i=2;i<=k;i++){
		if(m%i==0){
			res=res-res/i;
			while(m%i==0)
			m/=i;
		}
	}
	if(m>1)
	res=res-res/m;
	return res;
}

LL multi(LL a,LL b,LL m){
    LL ret=0;
    while(b>0){
        if(b&1) ret=(ret+a)%m;
        b>>=1;
        a=(a<<1)%m;
    }
    return ret;
}

LL quick(LL a,LL k,LL m){
	LL ans=1;
	while(k){
		if(k&1)
		ans=multi(ans,a,m);
		k=(k>>1);
		a=multi(a,a,m);
	}
	return ans;
}

int main(){
	LL l; int kase=0;
	while(scanf("%I64d",&l),l){
		if(l%16==0||l%5==0) {
			printf("Case %d: 0\n",++kase);
			continue;
		}
		cnt=0;
		LL m=l*9/gcd(l,(LL)8);
		LL phi=Euler(m);
		LL ans;
		LL k=(LL)sqrt((double)phi);
		for(LL i=1;i<=k;i++){
			if(phi%i==0){
				fac[cnt++]=i;
				fac[cnt++]=phi/i;
			}
		}
		sort(fac,fac+cnt);
		for(int i=0;i<cnt;i++){
			ans=quick((LL)10,fac[i],m);
			if(ans==1){
				printf("Case %d: %I64d\n",++kase,fac[i]);
				break;
			}
		}
	}
	return 0;
}

  

时间: 2024-08-29 03:54:39

POJ 3696的相关文章

poj 3696 欧拉函数

poj 3696 题意: 给出一个数字L,求出最短的888...8能被L整除,输出最短的长度. 限制: 1 <= L <= 2*10^9 思路: 设x为最小长度 888...8=(10^x-1)/9*8 由题意得: (10^x-1)/9*8 % L=0 -> (10^x-1)*8 % (9L) = 0 -> (10^x-1) % (9L/gcd(L,8)) = 0 -> 10^x % (9L/gcd(L,8)) = 1 这个是一个离散对数的问题,第一个想到的是用拓展BSGS做

poj 3696 The Luckiest number 欧拉函数在解a^x=1modm的应用

题意: 给一个L,求长度最小的全8数满足该数是L的倍数. 分析: 转化为求方程a^x==1modm.之后就是各种数学论证了. 代码: //poj 3696 //sep9 #include <iostream> #include <algorithm> using namespace std; typedef long long ll; ll L; ll factor[65536]; ll mul(ll x,ll y,ll p) { ll ret=0; while(y){ if(y&

POJ - 3696 同余

给定\(L\),求最小的\(x\)满足\(L|8(10^x-1)\) /*H E A D*/ inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll euler(ll n){ ll ans=n; for(ll i = 2; i*i <= n; i++){ if(n%i==0){ ans=ans/i*(i-1); while(n%i==0) n/=i; } } if(n>1) ans=ans/n*(n-1); return ans; } ll fm

POJ 3422 矩阵取数 最小费用流拆点+负边

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9153   Accepted: 3696 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

POJ——T2271 Guardian of Decency

http://poj.org/problem?id=2771 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5932   Accepted: 2463 Description Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is

POJ——T2446 Chessboard

http://poj.org/problem?id=2446 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18560   Accepted: 5857 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of c

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+