poj 2154 Color

原创 2013年12月02日 11:26:16

            Polya + Euler优化。由于n太大,所以需要用Euler优化。设L = n  / gcd(n, i),t = i / gcd(i, n),则gcd(L,  t) = 1.又有i < n所以,t  < L,且t和L互质。于是满足gcd(n, i) = n / L的i的个数为Euler(L)。对于题目原本的求和式应该是sum(pow(n, gcd(i, n) - 1))。所以我们枚举n的所有因子L,然后求和式就变成了

          sum(Euler(L) * pow(n, n / L - 1))。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
#define REP(i, n) for(int i = 0; i < n; i ++)
using namespace std;
const int N = 100100;
bool isp[N];
vector<int> p;

void get_P()
{
    CLR(isp, true);p.clear();
    for(int i = 2; i < N; i ++)
    {
        if(isp[i])
        {
            p.push_back(i);
            if(i < 1111) for(int j = i * i; j < N; j += i)
            {
                isp[j] = false;
            }
        }
    }
}

int Euler_phi(int n)
{
    int ret = n;
    for(int i = 0; p[i] * p[i] <= n; i ++) if(n % p[i] == 0)
    {
        ret = ret / p[i] * (p[i] - 1);
        while(n % p[i] == 0) n /= p[i];
    }
    if(n > 1) ret = ret / n * (n - 1);
    return ret;
}

int Pow(int a, int b, int mod)
{
    int ret = 1;a %= mod;
    while(b)
    {
        if(b & 1) ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret;
}

int main()
{
    int n, ans, mod, x;
    get_P();
    scanf("%d", &x);
    while(x --)
    {
        scanf("%d%d", &n, &mod);ans = 0;
        for(int i = 1; i * i <= n; i ++)
        {
            if(n % i != 0) continue;
            ans += Euler_phi(i) % mod * Pow(n, n / i - 1, mod) % mod;
            if(n / i != i)
                ans += Euler_phi(n / i) % mod * Pow(n, i - 1, mod) % mod;
            ans %= mod;
        }
        printf("%d\n", ans);
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。转载请标注:blog.csdn.net/ok_again

相关文章推荐

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

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7630   Accepted...

POJ 2154 Color(Polya原理+欧拉函数)

题目链接: POJ 2154 Color 题意: nn个颜色涂nn个珠子的项链,考虑旋转,求本质不同的项链数?, 分析: 根据PolyaPolya原理可得Ans=∑i=1nngcd(n,i)...
  • Ramay7
  • Ramay7
  • 2016年06月09日 21:37
  • 250

POJ 2154 Color Polya定理+欧拉函数

/* 题目要求:给出两个整数n和p,代表n个珠子,n种颜色,要求不同的项链数,并对结果mod(p)处理。 置换只有旋转一种方式,那么共有n个置换 基本知识:环的个数为gcd(n , i) , 长度L...

poj2154 color (polya定理+欧拉函数)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10277   Accepte...

POJ - 2154 Color(波利亚计数)(欧拉函数)

POJ - 2154 Color(波利亚计数)(欧拉函数)

POJ 2154 Color Ploya定理

来源:http://poj.org/problem?id=2154 题意:用n种颜色去涂长度为n的项链,问有多少种方法,最后取模。 思路:很容易看出是一道Ploya定理的题目,但是由于n的规模太大...
  • wmn_wmn
  • wmn_wmn
  • 2012年08月02日 15:29
  • 664

poj 2154 Color( polya 计数)

Problem LinkColor 大意:nn种颜色给nn条项链着色,问方法数,旋转视为同一种。Analysispolya定理 1N∑Nk=1Ngcd(k,N)\frac{1}{N}\sum_{k...

POJ-2154-Color(Pólya)

链接:http://poj.org/problem?id=2154 //#include #pragma comment(linker, "/STACK:1024000000,102400...

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

http://poj.org/problem?id=2154 大致题意:由n个珠子,n种颜色,组成一个项链。要求不同的项链数目,旋转后一样的属于同一种,结果模p。 n个珠子应该有n...

POJ 2154 Color 【polya+dfs】

看来有必要变得更加强大啊......... 141MS #include #include #include using namespace std; const int maxn=1...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 2154 Color
举报原因:
原因补充:

(最多只允许输入30个字)