POJ 2154 Color (ploya欧拉函数)

ploya定理,然后公式利用欧拉函数优化,gcd必然是因子,这样只要枚举因子,每个因子利用欧拉函数计算出现次数

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int t, n, p;

int pow_mod(int x, int k) {
    x %= p;
    int ans = 1;
    while (k) {
        if (k&1) ans = ans * x % p;
        x = x * x % p;
        k >>= 1;
    }
    return ans;
}

int phi(int n) {
    int ans = n;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            ans = ans / i * (i - 1);
            while (n % i == 0) n /= i;
        }
    }
    if (n > 1) ans = ans / n * (n - 1);
    return ans % p;
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &p);
        int ans = 0;
        for (int i = 1; i * i <= n; i++) {
            if (n % i == 0) {
                ans = (ans + pow_mod(n, i - 1) * phi(n / i) % p) % p;
                if (n / i != i) {
                    int tmp = n / i;
                    ans = (ans + pow_mod(n, tmp - 1) * phi(n / tmp) % p) % p;
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-11-04 11:21:10

POJ 2154 Color (ploya欧拉函数)的相关文章

POJ 2478 Farey Sequence( 欧拉函数 + 法雷数列 )

POJ 2478 Farey Sequence ( 欧拉函数 + 法雷数列 ) #include <cstdio> #include <cstring> using namespace std; #define MAXN 1000005 typedef long long LL; int vis[ MAXN ], prime[ MAXN ], cnt, n; LL phi[ MAXN ]; void get_phi_prime( int N ) { phi[1] = 1; cnt

poj2409 &amp; 2154 polya计数+欧拉函数优化

这两个题都是项链珠子的染色问题 也是polya定理的最基本和最经典的应用之一 题目大意: 用m种颜色染n个珠子构成的项链,问最终形成的等价类有多少种 项链是一个环.通过旋转或者镜像对称都可以得到置换 旋转可以旋转 i=[1,n]次..画图可以看出循环节有gcd(n,i)个 镜像对称的置换画个图也是很容易找的 然后通过polya定理就可以容易的求出等价类的种数了 2409就是这样一个裸题,以下为ac代码 #include <iostream> #include <stdio.h> #

POJ 2407 Relatives(欧拉函数入门题)

Relatives Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if there are no integers x > 1, y > 0, z > 0 such that a = xy and b = xz. Input There are several t

POJ 1284 Primitive Roots 欧拉函数模板题

#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #include <ctime> #include <io

POJ 2407 Relatives(欧拉函数)

Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11801   Accepted: 5780 Description Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if ther

poj 2154 Color 欧拉函数优化的ploya计数

枚举位移肯定超时,对于一个位移i,我们需要的是它的循环个数,也就是gcd(i,n),gcd(i,n)个数肯定不会很多,因为等价于n的约数的个数. 所以我们枚举n的约数,对于一个约数k,也就是循环个数为n/k这样的个数有phi[k]种,证明网上有很多.所以答案就是 phi[k]*(pow(n,n/k)) (k是n的所有约数) 由于约数会很大所以不能打表,只能单个算. 再由于最后要除以n,如果做除法就不能直接取模,所以我们在算每一次pow(n,n/k)的时候,都少乘一个n,这样就相当于除法了. #i

[ACM] POJ 2154 Color (Polya计数优化,欧拉函数)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7630   Accepted: 2507 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 th

poj 2154 Color(polya计数 + 欧拉函数优化)

http://poj.org/problem?id=2154 大致题意:由n个珠子,n种颜色,组成一个项链.要求不同的项链数目,旋转后一样的属于同一种,结果模p. n个珠子应该有n种旋转置换,每种置换的循环个数为gcd(i,n).如果直接枚举i,显然不行.但是我们可以缩小枚举的数目.改为枚举每个循环节的长度L,那么相应的循环节数是n/L.所以我们只需求出每个L有多少个i满足gcd(i,n)= n/L,就得到了循环节数为n/L的个数.重点就是求出这样的i的个数. 令cnt = gcd(i,n) =

POJ 2154 Color(组合数学-波利亚计数,数论-欧拉函数,数论-整数快速幂)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7693   Accepted: 2522 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 th