POJ2154 Color(Polya定理)

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 11654   Accepted: 3756

Description

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.

Input

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.

Output

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

Sample Input

5
1 30000
2 30000
3 30000
4 30000
5 30000

Sample Output

1
3
11
70
629

Source

POJ Monthly,Lou Tiancheng

Polya定理:

假设$G$是$p$个对象的一个置换群,用$m$种颜色涂染$p$个对象,则不同颜色的方案数为

$L = \frac{1}{|G|}\sum_{g_i \in G}m^{c(g_i)}$

$G = \{g_1, g_2, \dots g_s \}$,$c(g_i)$为置换$g_i$的循环节数

本题而言第$i$种置换的循环节数为$gcd(n, i)$

因此答案为$L = \frac{1}{n}\sum_{i = 1}^n n^{gcd(i, n}$

枚举约数,用欧拉函数计算,时间复杂度$O(T\sqrt(N) f(n))$,$f(n)$表示小于$\sqrt(n)$的质因子的个数

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#define LL long long
const int MAXN = 1e5 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = getchar();}
    while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
    return x * f;
}
int T, N, mod;
int fastpow(int a, int p, int mod) {
    int base = 1; a %= mod;
    while(p) {
        if(p & 1) base = (base * a) % mod;
        a = (a * a) % mod; p >>= 1;
    }
    return base % mod;
}
int prime[MAXN], tot, vis[MAXN];
void Prime() {
    for(int i = 2; i <= MAXN - 10; i++) {
        if(!vis[i]) prime[++tot] = i;
        for(int j = 1; j <= tot && prime[j] * i <= MAXN - 10; j++) {
            vis[i * prime[j]] = 1;
            if(!i % prime[j]) break;
        }
    }
}
int phi(int x, int mod) {
    int limit , ans = x;
    for(int i = 1; i <= tot && prime[i] * prime[i] <= x; i++) {
        if(!(x % prime[i])) {
            ans = ans - ans / prime[i];
            while((x % prime[i]) == 0) x /= prime[i];
        }
    }
    if(x > 1) ans = ans - ans / x;
//    printf("%d", ans % mod);
    return ans % mod;
}
main() {
    T = read();
    Prime();
    while(T--) {
        N = read(); mod = read();
        int ans = 0, now = N;
        for(int d = 1; d * d<= N; d++) {
            if(d * d == N)
                ans = (ans + fastpow(N, d - 1, mod) % mod * phi(N / d, mod) % mod) % mod;
            else if( (N % d) == 0) {
                ans = (ans + fastpow(N, d - 1, mod) * phi(N / d, mod) + fastpow(N, N / d - 1, mod) * phi(d, mod)) % mod;
            }

            //printf("%d\n", ans);
        }
        //if(now > 0) ans += fastpow(N, now - 1, mod) * phi(N / now, mod);
        printf("%d\n", ans % mod);
    }
}

原文地址:https://www.cnblogs.com/zwfymqz/p/9293465.html

时间: 2024-10-10 04:38:24

POJ2154 Color(Polya定理)的相关文章

POJ2154 Color polya定理+欧拉定理

由于这是第一天去实现polya题,所以由易到难,先来个铺垫题(假设读者是看过课件的,不然可能会对有些“显然”的地方会看不懂): POJ1286 Necklace of Beads :有三种颜色,问可以翻转,可以旋转的染色方案数,n<24. 1,n比较小,恶意的揣测出题人很有可能出超级多组数据,所以先打表. 2,考虑旋转: for(i=0;i<n;i++) sum+=pow(n,gcd(n,i)); 3,考虑翻转: if(n&1) sum+=n*pow(3,n/2+1) ; else {

【poj2154】Color Polya定理+欧拉函数

题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题解 Polya定理+欧拉函数 根据 poj2409 中得到的结论,答案为: $\frac{\sum\limits_{i=1}^nn^{\gcd(i,n)}}n=\sum\limits_{i=1}^nn^{\gcd(i,n)-1}$ 由于 $n$ 有 $10^9$ 之大,因此考虑优化这个式子. 枚举

[POJ1286&amp;POJ2154&amp;POJ2409]Polya定理

Polya定理 L=1/|G|*(m^c(p1)+m^c(p2)+...+m^c(pk)) G为置换群大小 m为颜色数量 c(pi)表示第i个置换的循环节数 如置换(123)(45)(6)其循环节数为3 ------------------------------------------------------------------------------------------- POJ1286&POJ2409 都是简单的处理串珠子的问题. 题目中隐藏着3种不同的置换类别. 1.旋转 注意不

POJ2154 Color【Polya定理】【欧拉函数】【整数快速幂】

题目链接: http://poj.org/problem?id=2154 题目大意: 给定 N 种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为 N 的项链. 问能做成多少种不重复的项链,最后结果对 P 取模.并且两条项链相同,当且仅当两条 项链通过旋转后能重合在一起,且对应珠子的颜色相同. 解题思路: Polya定理的应用.先来看Polya定理. Polya定理:设 G = {a1,a2,-,ag}是 N 个对象的置换群,用 M 种颜色给这 N 个 对象着色,则不同的着色 方案数为

置换群和Burnside引理,Polya定理

定义简化版: 置换,就是一个1~n的排列,是一个1~n排列对1~n的映射 置换群,所有的置换的集合. 经常会遇到求本质不同的构造,如旋转不同构,翻转交换不同构等. 不动点:一个置换中,置换后和置换前没有区别的排列 Burnside引理:本质不同的方案数=每个置换下不动点的个数÷置换总数(一个平均值) Polya定理:一个置换下不动点的个数=颜色^环个数.(辅助Burnside引理,防止枚举不动点复杂度过高) 这篇文章写得很详细了(具体的在此不说了): Burnside引理与Polya定理 **特

Polya定理,Burnside引理(转)

设G是一个集合,*是G上的二元运算,如果(G,*)满足下面的条件: 封闭性:对于任何a,b∈G,有a*b∈G; 结合律:对任何a,b,c∈G有(a*b)*c=a*(b*c); 单位元:存在e∈G,使得对所有的a∈G,都有a*e=e*a=a; 逆元:对于每个元素a∈G,存在x∈G,使得a*x=x*a=e,这个时候记x为a-1,称为a的逆元,那么则称(G,*)为一个群. 例:G={0,1,2,3,4....n-1}那么它在mod n加法下是一个群. 群元素的个数有限,称为有限群,且其中元素的个数称为

POJ_2409 Let it Bead(Polya定理)

描述 "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets. However,

Burnside引理与Polya定理

Burnside引理与Polya定理 Burnside引理与Polya定理是有关组合数学的两条十分重要的定理(引理),但是网上的一些资料大多晦涩难懂或者与实际并不相关联,因此在这里做一些浅显的解读,希望通过此文章可以让这两条定理(引理)能够发挥其作用. PS:引理与定理的区别: Ψ引理是数学中为了取得某个更好的定理而作为步骤被证明的命题,其意义并不在于自身被证明,而在于为达成最终定理作出贡献. Ψ一个引理可用于证明多个定理.数学中存在很多著名的引理,这些引理可能对很多问题的解决有帮助.例如欧几里

[POJ2409]Let it Bead - Polya定理

[POJ2409]Let it Bead Time Limit: 1000MS   Memory Limit: 65536K Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found