您的位置:首页 > 理论基础 > 计算机网络

http://acm.hdu.edu.cn/showproblem.php?pid=3307 (欧拉 + 推导公式 + gcd)

2010-08-08 02:08 447 查看
]/*
* 	解题: 题目描述很简单的说,然后我们可以推得这样一个公式:
an = x^n * a0 + y*sigma(x+x^2+....+x^(n-1) )  --->  an = x^n*a0 + y/(x-1)*(x^n-1);
因为题目 给定  y mod (x-1) = 0 ;
那么 如果an % a0 == 0 ; 那么 可以表示 ( y/(x-1)*(x^n-1) )%a0 == 0;
设 m = y/(x-1), g = gcd(a0,m),那么我们可以得到 ( x^n-1)%(a0/g) == 0;设c = a0/g;
转化为 x^n == 1(mod c );
那么我们可以得到  当 gcd( c,x ) != 1 时  无解
当gcd( c,x ) == 1 时,我们可以得到  x^eular(c) == 1 ( mod c);
但是这不一定是最小的,所以我们要枚举x的约数,求得最小的。
*/
import java.io.*;
import java.util.*;
import java.math.*;
public class Main3307{
static final int N = 100000;
static long num[] = new long
;
//public static void main(String[] args){
public static void main(String[] args)throws IOException{
StreamTokenizer cin = new StreamTokenizer(new BufferedReader (new InputStreamReader(System.in)));
long x, y, a;
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
//Scanner cin = new Scanner(System.in);
//while(cin.hasNext()){
while(cin.nextToken() != StreamTokenizer.TT_EOF){
//x = cin.nextLong();
//y = cin.nextLong();
//a = cin.nextLong();
x = (long)cin.nval;
cin.nextToken();
y = (long)cin.nval;
cin.nextToken();
a = (long)cin.nval;
long m = y / (x - 1);
if(m == 0){
//System.out.println("1");
out.println("1");
continue;
}
long g = gcd(a, m);
long c = a / g;
if(gcd(c, x) != 1){
//System.out.println("Impossible!");
out.println("Impossible!");
continue;
}
long ans = Euler(c);
int len = 0;
for(int i = 1; i * i <= ans; i++){
if(ans % i == 0){
num[len++] = i;
if(ans % i != i){
num[len++] = ans / i;
}
}
}
Arrays.sort(num, 0, len);
int i;
for(i = 0; i < len; i++){
if(erfen(x, num[i], c) == 1)
break;
}
//System.out.println(num[i]);
out.println(num[i]);

}
out.flush();

}

static long gcd(long a, long b)
{
if(a < b)
{
long temp = a;
a = b;
b = temp;
}
/*
if(b == 0) return a;
return gcd(b, a % b);
*/
while(b > 0)
{
//a = b;
long t = a % b;
a = b;
b = t;
}
return a;

}
static long Euler(long n){
long sum = n;
long temp = n;
for(long i = 2; i * i <= n; i++){
if(temp % i == 0){
sum = sum / i * ( i - 1);
while(temp % i == 0)
temp /= i;
}
}
if(temp > 1)
sum = sum / temp * (temp - 1);
return sum;
}

static long erfen(long a, long b, long mod){
long temp = a % mod;
long result = 1;
while(b > 0){
if(b % 2 == 1){
result  *= temp;
result %= mod;
b--;
}
else{
temp *= temp;
temp %= mod;
b >>= 1;
}
}
return result;
}
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  import string c class