http://poj.org/problem?id=2154
题意:经典polya题
解析:差别就是项链数目不定,采用欧拉函数,求出所有情况求解即可
// File Name: poj2154.cpp
// Author: bo_jwolf
// Created Time: 2013年10月08日 星期二 17:46:30
#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
using namespace std;
int Case;
typedef long long INT;
int eular( int n ){
int i = 0;
int ans = 1;
for( int i = 2; i * i <= n; ++i ){
if( n % i == 0 ){
ans *= ( i - 1 );
n /= i;
while( n % i == 0 ){
ans *= i;
n /= i;
}
}
}
if( n > 1 )
ans *= n - 1;
return ans;
}
INT power( long long a, int b, int p ){
INT ans = 1, temp = a;
while( b ){
if( b & 1 ){
ans = ( ans * a )% p;
}
b >>= 1;
a = ( a * a )% p;
}
return ans;
}
INT calc( int n, int p ){
INT ans = 0;
for( int i = 1; i * i <= n; ++i ){
if( n % i == 0 ){
ans = ( ans + eular( i ) * power( n , n / i - 1, p ) ) % p;
if( i * i != n )
ans = ( ans + eular( n / i ) * power( n, i - 1, p ) ) % p;
}
}
return ans;
}
int main(){
scanf( "%d", &Case );
int i, n, p;
for( int i = 1; i <= Case; ++i ){
scanf( "%d%d", &n, &p );
printf( "%I64d\n", calc( n, p ) );
}
return 0;
}