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) = n/L。

那么cnt | i。令i = cnt*t(0 <= t <= L)。

又 n = cnt * L ;

所以gcd(i,n) = gcd( cnt*t, cnt*L) = cnt。

满足上式的条件是 gcd(t,L) = 1。

而这种t 有Eular(L)个。

因此循环节个数是n/L的置换个数有Eular(L)个。

參考博客:http://blog.csdn.net/tsaid/article/details/7366708



代码中求欧拉函数是基于素数筛的,素数仅仅需筛到sqrt(1e9)就可以。我在筛素数的同一时候递推的记录了sqrt(1e9)以内的Eular(n),用phi[]表示。这样会快那么一点点。



#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#define LL long long
#define _LL __int64
#define eps 1e-8
#define PI acos(-1.0)
using namespace std; const int maxn = 35000;
const int INF = 0x3f3f3f3f; int n,p;
int ans;
int prime[maxn];
int flag[maxn];
int prime_num;
int phi[maxn]; int mod_exp(int a, int b, int c)
{
int res = 1;
a = a%c;
while(b)
{
if(b&1)
res = (res*a)%c;
a = (a*a)%c;
b >>= 1;
}
return res;
} //素数筛并记录maxn以内的Eular(n)。用phi[]表示
void get_prime()
{
memset(flag,0,sizeof(flag));
prime_num = 0;
phi[1] = 1;
for(int i = 2; i <= maxn; i++)
{
if(!flag[i])
{
prime[++prime_num] = i;
phi[i] = i-1;
} for(int j = 1; j <= prime_num && i*prime[j] <= maxn; j++)
{
flag[i*prime[j]] = 1;
if(i % prime[j] == 0)
phi[i*prime[j]] = phi[i] * prime[j];
else phi[i*prime[j]] = phi[i] * (prime[j]-1);
}
}
} int Eular(int n)
{
if(n < maxn)
return phi[n] % p;
//求大于maxn的Eular(n)
int res = n;
for(int i = 1; prime[i]*prime[i] <= n && i <= prime_num; i++)
{
if(n % prime[i] == 0)
{
res -= res/prime[i];
while(n%prime[i] == 0)
n = n/prime[i];
}
}
if(n > 1)
res -= res/n;
return res%p;
} int main()
{ int test;
get_prime();
scanf("%d",&test); while(test--)
{
scanf("%d %d",&n,&p);
ans = 0;
for(int l = 1; l*l <= n; l++)
{
if(l*l == n)
{
ans = (ans + Eular(l)*mod_exp(n,l-1,p))%p;
}
else if(n%l == 0) //循环节长度为l,那么n/l也是循环节长度
{
ans = (ans + Eular(l)*mod_exp(n,n/l-1,p))%p;
ans = (ans + Eular(n/l)*mod_exp(n,l-1,p))%p;
}
}
printf("%d\n",ans);
}
return 0;
}

poj 2154 Color(polya计数 + 欧拉函数优化)的更多相关文章

  1. poj2409 & 2154 polya计数+欧拉函数优化

    这两个题都是项链珠子的染色问题 也是polya定理的最基本和最经典的应用之一 题目大意: 用m种颜色染n个珠子构成的项链,问最终形成的等价类有多少种 项链是一个环.通过旋转或者镜像对称都可以得到置换 ...

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

    题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题 ...

  3. POJ2154 Color【 polya定理+欧拉函数优化】(三个例题)

    由于这是第一天去实现polya题,所以由易到难,先来个铺垫题(假设读者是看过课件的,不然可能会对有些“显然”的地方会看不懂): 一:POJ1286 Necklace of Beads :有三种颜色,问 ...

  4. poj2154Color polya定理+欧拉函数优化

    没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻 ...

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

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

  6. HDU 2239 polya计数 欧拉函数

    这题模数是9937还不是素数,求逆元还得手动求. 项链翻转一样的算一种相当于就是一种类型的置换,那么在n长度内,对于每个i其循环节数为(i,n),但是由于n<=2^32,肯定不能直接枚举,所有考 ...

  7. POJ 2154 color (polya + 欧拉优化)

    Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). You ...

  8. POJ 2478 Farey Sequence(欧拉函数前n项和)

    A - Farey Sequence Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  9. poj 2480 Longge's problem [ 欧拉函数 ]

    传送门 Longge's problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7327   Accepted: 2 ...

随机推荐

  1. .get(),eq()的区别

    .get(),eq()的区别 eq:返回是一个jquery对象作用是将匹配的元素集合缩减为一个元素.这个元素在匹配元素集合中的位置变为0,而集合长度变成1. get:是一个html对象数组作用是取得其 ...

  2. [terry笔记]一个在线美化sql的网站

    http://www.dpriver.com/pp/sqlformat.htm 甚是好用.

  3. NYIST 489 哭泣天使

    哭泣天使时间限制:1000 ms | 内存限制:65535 KB难度:5 描述Doctor Who乘着Tardis带着Amy来到了一个星球,一开Tadis大门,发现这个星球上有个壮观的石像群,全是一些 ...

  4. oracle用户锁定

    https://www.cnblogs.com/lostyue/archive/2011/12/06/2278063.html

  5. spring boot和maven的约定大于配置体现在哪些方面

    spring boot和maven的约定大于配置体现在哪些方面? 两者都遵从了约定大于配置的路线 约定优于配置体现点: 1.maven的目录文件结构 1)默认有resources文件夹,存放资源配置文 ...

  6. C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题

    代码例如以下: #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&am ...

  7. atitit。企业组织与软件project的策略 战略 趋势 原则 attilax 大总结

    atitit. 企业组织与软件project的策略 战略 趋势 原则 attilax 大总结 1. 战略规划,适当的过度设计 1 2. 跨平台化 1 3. 可扩展性高于一切 1 4. 界面html5化 ...

  8. 任务调度器quartz的使用

    1.quartz的获取. 可參照:Quartz任务调度模型实例 2.开发思路: 要使用定时器quartz.先弄清楚三个概念:调度器.任务.触发器.开发也是依照这三个方面来开发, 1>写一个Job ...

  9. we标签

    功能: ·        辅助标签.配合其它标签使用,防止与标准html标签冲突 ·        别名为test 使用方法: <we [name=key]>[value]</we& ...

  10. 三种SVM的对偶问题

    一.SVM原问题及要变成对偶问题的解决办法 对于SVM的,我们知道其终于目的是求取一分类超平面,然后将新的数据带入这一分类超平面的方程中,推断输出结果的符号,从而推断新的数据的正负. 而求解svm分类 ...