• POJ2154 Color 【Polya定理 + 欧拉函数】


    题目

    Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of the necklace can be produced. You should know that the necklace might not use up all the N colors, and the repetitions that are produced by rotation around the center of the circular necklace are all neglected.

    You only need to output the answer module a given number P.

    输入格式

    The first line of the input is an integer X (X <= 3500) representing the number of test cases. The following X lines each contains two numbers N and P (1 <= N <= 1000000000, 1 <= P <= 30000), representing a test case.

    输出格式

    For each test case, output one line containing the answer.

    输入样例

    5
    1 30000
    2 30000
    3 30000
    4 30000
    5 30000

    输出样例

    1
    3
    11
    70
    629

    题解

    题意:

    用n种颜色染n个点的环,问有多少本质不同的染法

    Polya定理##

    我们设置换群为G,(c(i))表示置换i的循环节个数,m为色数,L为答案
    (L = frac{1}{mid G mid} sum_{i=1}^{s} m^{c(i)})

    本题有n个置换,置换i循环节个数为(gcd(n,i))
    那么我们有:
    (ans = frac{1}{n} sum_{i=1}^{n} n^{gcd(n,i)})
    (qquad = frac{1}{n} sum_{d|n} n^d sum_{i=1}^{n}[gcd(n,i)==1])
    (qquad = sum_{d|n} n^{d-1} sum_{i=1}^{n/d}[gcd(n/d,i)==1])
    (qquad = sum_{d|n} n^{d-1} phi(n/d))

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
    	return out * flag;
    }
    int P,prime[maxn],primei;
    bool isn[maxn];
    void init(){
    	for (int i = 2; i < maxn; i++){
    		if (!isn[i]) prime[++primei] = i;
    		for (int j = 1; j <= primei && i * prime[j] < maxn; j++){
    			isn[i * prime[j]] = true;
    			if (i % prime[j] == 0) break;
    		}
    	}
    }
    int qpow(int a,int b){
    	int ans = 1;
    	for (; b; b >>= 1,a = (LL)a * a % P)
    		if (b & 1) ans = (LL)ans * a % P;
    	return ans;
    }
    int phi(int n){
    	int ans = n;
    	for (int i = 1; prime[i] * prime[i] <= n; i++){
    		int p = prime[i];
    		if (n % p == 0){
    			ans = ans - ans / p;
    			while (n % p == 0) n /= p;
    		}
    	}
    	if (n > 1) ans = ans - ans / n;
    	return ans % P;
    }
    int cal(int n,int d){
    	return qpow(n,d - 1) * phi(n / d) % P;
    }
    int main(){
    	init();
    	int T = read(),n,ans;
    	while (T--){
    		n = read(); P = read(); ans = 0;
    		for (int i = 1; i * i <= n; i++){
    			if (n % i == 0){
    				ans = (ans + cal(n,i)) % P;
    				if (i * i != n) ans = (ans + cal(n,n / i)) % P;
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    好听的歌 好音乐
    dubbox编译
    [HDU3038]How Many Answers Are Wrong(并查集)
    [POJ1733]Parity game(并查集 + 离散化)
    [POJ1703]Find them, Catch them(并查集)
    [luoguP2024] 食物链(并查集)
    [luoguP3355] 骑士共存问题(二分图最大独立集)
    火星探险问题
    [CODEVS1917] 深海机器人问题(最小费用最大流)
    [CODEVS1916] 负载平衡问题(最小费用最大流)
  • 原文地址:https://www.cnblogs.com/Mychael/p/8318545.html
Copyright © 2020-2023  润新知