Color

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;

}


 

 

你可能感兴趣的:(color)