Color

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 7873   Accepted: 2565

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
 

Mean:

给你一个包含N个珠子的项链,现在有N种颜色,让你从这N种颜色中选择一些颜色来将这些珠子染色,问可以染出多少种不同的珠子。

analyse:

对于n比较小的情况我们可以直接暴力枚举置换群并统计其对应的C(f),考虑旋转i个珠子的循环群,我们可以证明其对应的不动的染色方案C(fi)=n^gcd(i,n)。为什么呢?我们可以这样考虑,假设珠子编号为0~n-1,对于旋转i个珠子的循环群,由于相邻间的珠子对应的旋转后位置还是相邻,所以这个循环群的环必然是大小相等的。假设其环的大小为T,那么就有(T*i)%n=0。假设T*i=k*n,i=g*x,n=g*y,其中g=gcd(i,n)。那么T=k*y/x,因为k为整数,x、y互质,所以使得T最小且为正整数的k=x,那么T=y,整个循环群中环的个数=n/T=g。所以我们可以得到C(fi)=n^gcd(i,n)。那么这个题目就转化为求sum{n^gcd(i,n)},1<=i<=n。

但是n<=10^9,这个数据范围太大,直接枚举必然超时,我们要考虑优化。观察上面的公式,我们发现虽然i的范围很大,但是gcd(i,n)的值却不多,最多为n的因子的个数。如果我们可以很快求出gcd(i,n)=g时i的个数,那么我们就能够得到一个很高效的算法。假设i=g*x,n=g*y,gcd(i,n)=g的条件为x、y互质,又因为1<=x<=y。所以满足条件的x的个数就是[1,y]里和y互质的数的个数,这就等于phi(y)。欧拉函数的值可以在O(n^(1/2))的复杂度内算出来,于是我们就得到了一个高效的算法。

Time complexity:O(n^(/12))

Source code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std; int n, yu; const int NN=10000000;
bool v[NN];
int p[NN];
int len=-1;
void make_p()
{
int i,j;
for(i=2; i<NN; ++i)
{
if(!v[i]) p[++len] = i;
for(j=0; j<=len && i*p[j] < NN; ++j)
{
v[i*p[j]] =1;
if(i%p[j] == 0) break;
}
}
} int work(int n) {
int temp = n;
for (int i = 0; i < len && p[i]*p[i] <= temp; ++i)
{
if (temp % p[i] == 0) {
n -= n/p[i];
do {
temp /= p[i];
}while (temp % p[i] == 0);
}
}
if (temp != 1) {
n -= n/temp;
}
return n%yu;
} int solve(int m) {
int ans = 1;
int s = n%yu;
int temp = m;
while (temp > 0) {
if (temp&1) {
ans = (ans * s) % yu;
}
s = (s*s)%yu;
temp >>= 1;
}
return ans;
} int main() {
make_p();
int t;
scanf("%d", &t);
while (t--) {
scanf("%d %d", &n, &yu);
int res = 0;
for (int i = 1; i*i <= n; ++i) {
if (i*i == n)
{
res = (res + work(i)*solve(i-1))%yu;
}
else if (n%i == 0)
{
res = (res + work(i)*solve(n/i-1) + work(n/i)*solve(i-1))%yu;
}
}
printf("%d\n", res);
}
return 0;
}

  

组合数学 - 波利亚定理 --- poj : 2154 Color的更多相关文章

  1. poj 2154 Color < 组合数学+数论>

    链接:http://poj.org/problem?id=2154 题意:给出两个整数 N 和 P,表示 N 个珠子,N种颜色,要求不同的项链数, 结果 %p ~ 思路: 利用polya定理解~定理内 ...

  2. poj 2154 Color【polya定理+欧拉函数】

    根据polya定理,答案应该是 \[ \frac{1}{n}\sum_{i=1}^{n}n^{gcd(i,n)} \] 但是这个显然不能直接求,因为n是1e9级别的,所以推一波式子: \[ \frac ...

  3. poj 2154 Color——带优化的置换

    题目:http://poj.org/problem?id=2154 置换的第二道题! 需要优化!式子是ans=∑n^gcd(i,n)/n (i∈1~n),可以枚举gcd=g,则有phi( n/g )个 ...

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

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

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

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

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

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

  7. poj 2154 Color

    这是道标准的数论优化的polya题.卡时卡的很紧,需要用int才能过.程序中一定要注意控制不爆int!!!我因为爆intWA了好久=_=…… 题目简洁明了,就是求 sigma n^gcd(i,n):但 ...

  8. POJ 2154 Color [Polya 数论]

    和上题一样,只考虑旋转等价,只不过颜色和珠子$1e9$ 一样的式子 $\sum\limits_{i=1}^n m^{gcd(i,n)}$ 然后按$gcd$分类,枚举$n$的约数 如果这个也化不出来我莫 ...

  9. POJ 2154 Color ——Burnside引理

    [题目分析] 数据范围有些大. 然后遍求欧拉函数,遍求和就好了,注意取模. [代码] #include <cstdio> #include <cstring> #include ...

随机推荐

  1. 安装redis监控

    在修改登录中心的时候,数据存储在redis里面,需要对redis进行监控,使用的是Redis-Live 参考文章: http://www.nkrode.com/article/real-time-da ...

  2. C++ 代码换行

    1.字符串太长,换行显示,怎么办?2.使用反斜杠,如下: string str = "abcd\ 1234"; 注意:反斜杠后面不准有任何字符.下一行开头的制表符不包含在整个字符串 ...

  3. Android开发之蓝牙 --修改本机蓝牙设备的可见性,并扫描周围可用的蓝牙设备

    一. 修改本机蓝牙设备的可见性 二. 扫描周围可用的蓝牙设备 一.  清单文件AdroidManifest.xml: <uses-permission android:name="an ...

  4. VirtualBox不能为虚拟电脑 Ubuntu 打开一个新任务

    今天在用Vbox中的Ubuntu系统准备测试Python代码时,Vbox报了一个错误:"不能为虚拟电脑 Ubuntu 打开一个新任务".因为之前用的时候还好好的,也不知道是不是最近 ...

  5. BpBinder 转换为 BpCameraService 流程

    interface_cast<ICameraService>(binder) : 其中binder 为IBinder类型,实际为BpBinder interface_cast 定义在IIn ...

  6. 解决“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”问题(l转)

    同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65536个(DEX 64K problem),进而导致dex无法生成,也就无法生成APK文件. 解决办法如下: 1.谷 ...

  7. pecl install imagick

    steven@server:/var/www$ sudo pecl install imagickdownloading imagick-2.3.0.tgz ...Starting to downlo ...

  8. 使用aspose.cell导出excel需要注意什么?

    1.如果导出的数据源是汇总出来的,最好方法是将数据源放到缓存里面,当基本数据源变化的时候,在改变数据2.使用模板导出EXCEL,这样很多样式可以在模板文件里面直接设置,例如:默认打开页签,让列头固定3 ...

  9. Object-C Categories和Protocols

    Category 要扩展一个不可修改的类,通常的做法是为该类创建一个子类,在子类中实现想要实现的方法,在Object-C中,可以通过category来实现,并且实现方式更为简单. 现在有如下定义:一个 ...

  10. (转)关于tcp和udp的缓冲区

    (一)基础知识 IPv4 数据报最大大小是65535(16位),包括IPv4头部. IPv6 数据报最大大小是65575,包括40个字节的IPv4头部 MTU,这是由硬件规定的,如以太网的MTU是15 ...