ÌâÒ⣺´ËÌâ¸úPOJ 2409ÀàËÆ£¬Ö»²»¹ýÖ»¿¼ÂÇÐýת£¬²»¿¼ÂǷת£»
µ«ÊÇÐèÒªÓõ½¿ìËÙÃݺÍÅ·Àº¯ÊýµÄÓÅ»¯Çó½â¡£
/*
Ðýת£ºË³Ê±ÕëÐýתi¸ñµÄÖû»ÖУ¬Ñ»·µÄ¸öÊýΪgcd£¨i,n£©£¬
ÿ¸öÑ»·µÄ³¤¶ÈΪn/gcd£¨i,n£©¡£
Èç¹ûö¾ÙÐýתµÄ¸ñÊýi,¸´ÔÓ¶ÈÏÔÈ»½Ï¸ß¡£ÓÐûÓк÷½·¨ÄØ£¿
¿ÉÒÔ²»Ã¶¾Ùi,·´¹ýÀ´Ã¶¾ÙL.
ÓÉÓÚL|N,ö¾ÙÁËL,ÔÙ¼ÆËãÓжàÉÙ¸öiʹµÃ0<=i<=n-1²¢ÇÒL=gcd£¨i, n£©¡£
¼´gcd£¨i,n£©=n/L.
²»·ÁÉèa=n/L=gcd£¨i, n£©£¬
²»·ÁÉèi=a*tÔòµ±ÇÒ½öµ±gcd£¨L,t£©=1ʱ
Gcd£¨i,n£©=gcd£¨a*L,a*t£©=a.
ÒòΪ0<=i<n,ËùÒÔ0<=t<n/a=L.
ËùÒÔÂú×ãÕâ¸öÌõ¼þµÄtµÄ¸öÊýΪEuler£¨L£©¡£
*/
[cpp] view plaincopyprint
#include <cstdio>
#include <cstring>
using namespace std;
const int maxisp = 50000 + 10;
const int maxp = 8000 + 10;
int num,n,MOD;
int prime[maxp];
int isprime[maxisp];
inline void get_prime£¨£©
{
num=0;
for£¨int i=2;i<=maxisp;i++£©
if£¨£¡isprime[i]£©
{
prime[num++]=i;
for£¨int j=1;j*i<=maxisp;j++£©
isprime[i*j]=1;
}
}
inline int euler£¨int x£©
{
int res=x;
for£¨int i=0;i<num&&prime[i]*prime[i]<=x;i++£©
{
if£¨x%prime[i]==0£©
{
res=res/prime[i]*£¨prime[i]-1£©£»
while£¨x%prime[i]==0£©
x/=prime[i];
}
}
if£¨x>1£© res=res/x*£¨x-1£©£»
return res;
}
//¿ìËÙÃÝÄ£°æ ´Ë´¦µÄint¿É»»³Élong long
//£¨A*B£©%MOD
inline int mul£¨int a,int b,int mod£©
{
int res=0;
a%=mod,b%=mod;
while£¨b£©
{
if£¨b&1£©
{
res+=a;
res%=mod;
}
a¡¶=1;
if£¨a>=mod£© a%=mod;
b¡·=1;
}
return res;
}
//£¨A^N£©%MOD
inline int pow_mod£¨int a,int n,int mod£©
{
int res=1;
a%=mod;
while£¨n£©
{
if£¨n&1£© res=mul£¨res,a,mod£©£»
a=mul£¨a,a,mod£©£»
n¡·=1;
}
return res;
}
int main£¨£©
{
int T;
get_prime£¨£©£»
scanf£¨"%d",&T£©£»
while£¨T--£©
{
scanf£¨"%d%d",&n,&MOD£©£»
int ans=0,i;
for£¨i=1;i*i<n;i++£©
{
if£¨n%i==0£©//Ó㤶ÈΪLµÄÑ»·£¬¾Í»áÓ㤶ÈΪn/LµÄÑ»·¡£
ans=£¨ans+euler£¨i£©%MOD*pow_mod£¨n,n/i-1,MOD£©+euler£¨n/i£©%MOD*pow_mod£¨n,i-1,MOD£©£©%MOD;
}
if£¨i*i==n£©//ö¾ÙÑ»·³¤¶Èl,ÕÒ³öÏàÓ¦µÄiµÄ¸öÊý£ºgcd£¨i,n£©=n/l.
ans=£¨ans+euler£¨i£©*pow_mod£¨n,i-1,MOD£©£©%MOD;
printf£¨"%d\n",ans£©£»
}
return 0;
}