1204. Idempotents
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
The number
x is called an idempotent modulo
n if
x*
x =
x (mod
n)
Write the program to find all idempotents modulo
n, where
n is a product of two distinct primes
pand
q.
Input
First line contains the number
k of test cases to consider (1 ≤
k ≤ 1000). Each of the following
klines contains one number
n < 10
9
.
Output
Write on the
i-th line all idempotents of
i-th test case in increasing order. Only nonnegative solutions bounded by
n should be printed.
Sample
input | output |
---|---|
3 6 15 910186311 | 0 1 3 4 0 1 6 10 0 1 303395437 606790875 |
Problem Author: Pavel Atnashev
Problem Source: USU Internal Contest, March 2002
Problem Source: USU Internal Contest, March 2002
扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数),使它们满足贝祖定理。
通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)[1]。
有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a; //---很难找出一个这么实现的价值,因为扩展欧几里得还有更大的用途;个人认为定义全局数组更好,不用return r。
}
int r = exGcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
对于方程:x^2≡x(mod n)(n=p*q,p,q为两个不同的质数)
必定有解,且必为4个解(0,1(特解),px,qy,(0<x<q,0<y<p))。
#include<iostream>
#include<cstdio>
using namespace std;
int n,x,y;
bool pr[1000000];
int arr[10000],p,q;
int exGcd(int a,int b,int &x,int &y)
{
int gcd,tmp;
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
gcd=exGcd(b,a%b,x,y);
tmp=x;
x=y;
y=tmp-(a/b)*y;
}
return gcd;
}
int main()
{
int tes;
int i,j;
for(i=2; i<=100000; i++)
{
if(pr[i]==0)
{
arr[++arr[0]]=i;
}
for(j=1; j<=arr[0]&&arr[j]*i<=100000; j++)
{
pr[i*arr[j]]=1;
if(i%arr[j]==0)
break;
}
}
scanf("%d",&tes);
while(tes--)
{
scanf("%d",&n);
for(i=1; i<=arr[0]; i++)
{
if(n%arr[i]==0)
{
p=arr[i];
q=n/p;
break;
}
}
exGcd(p,q,x,y);
if(x>0)
{
while(x-q>0)
{
x-=q;
}
}
if(x<0)
{
while(x<0)
{
x+=q;
}
}
int xx=x*p;
exGcd(q,p,x,y);
if(x>0)
{
while(x-p>0)
{
x-=p;
}
}
if(x<0)
{
while(x<0)
{
x+=p;
}
}
int yy=x*q;
printf("0 1 ");
if(xx>yy)
printf("%d %d\n",yy,xx);
else
printf("%d %d\n",xx,yy);
}
return 0;
}