He's Circles

He wrote n letters "X" and "E" in a circle. He thought that there were 2n possibilities to do it, because each letter may be either "X" or "E". But Qc noticed that some different sequences of letters can be transformed one to another with a circular shift (thus representing actually the same circular string).
For example, strings "XXE"-"XEX"-"EXX" are actually the same.

Qc wants to know how many different circular strings of n letters exist. Help him to find that out.

Input

The input file contains a single integer 1 <= n <= 200000.

Output

Output a single integer --- the number circular strings of length n.

Sample Input

Sample test(s)
Input
Test #1
3

Test #2
4

Output
Test #1
4

Test #2
6

  这道题是等价类计数问题。
  由于是我写的第一题,我会把过程写的尽量详细,用以纪念。
  题意:有一个长度为N的环,上面写着’X’和’E’,问本质不同的环有多少种。(N不超过200000)。
  考虑用Pólya定理,答案是Σ(每个置换的不动点个数)/n,如何求不动点个数?这里枚举所有置换,假设当前枚举到的置换为"循环移动k位",d=(n,k),若1位置在当前置换下可以到3位置,则1位置和3位置处在同一循环,这时循环的个数就是d(每个循环经过n*k/d个点,由于每个间距为k,所以一个循环有n/d个点,那么就有d个循环),这对答案的贡献就是2^d(每个循环中可涂任意相同颜色,不影响其为不动点),所以就可以枚举d,这时我们可以知道与n的GCD为d的数有φ(n/d)个,那么这里答案则为1/n*Σ2^d*φ(n/d)。
  然后还要用高精度,真羡慕JAVA。
 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
int n,tot;
int phi[maxn],pri[maxn]; void Linear_Shaker(){
phi[]=;
for(int i=;i<=n;i++){
if(!phi[i]){
phi[i]=i-;
pri[++tot]=i;
}
for(int j=;j<=n;j++){
if(i*pri[j]>n)break;
if(i%pri[j]!=)
phi[i*pri[j]]=phi[i]*(pri[j]-);
else{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
}
}
} int POW[]={,,,};
const int mod=;
struct ExtInt{
int num[],len;
ExtInt(int x){len=;
memset(num,,sizeof(num));
do{
num[++len]=x%mod;
x/=mod;
}while(x);
} void Scf(){
char s[];scanf("%s",s+);
memset(num,,sizeof(num));len=;
for(int i=strlen(s+),cnt=;i>=;i--){
num[len]+=POW[cnt++]*(s[i]-'');
if(cnt==)cnt=,len+=;
}
} int operator [](int x){
return num[x];
} void Prf(){
printf("%d",num[len]);
for(int i=len-;i>=;i--)
printf("%04d",num[i]);
printf("\n");
}
}; ExtInt operator +(ExtInt a,int b){
ExtInt ret();
ret.len=a.len;
for(int i=,in=;i<=ret.len||in;i++){
ret.num[i]=a[i]+b+in;in=ret[i]/mod;
ret.num[i]%=mod;ret.len=max(ret.len,i);
}
return ret;
} ExtInt operator +(ExtInt a,ExtInt b){
ExtInt ret();
ret.len=max(a.len,b.len);
for(int i=,in=;i<=ret.len||in;i++){
ret.num[i]=a[i]+b[i]+in;in=ret[i]/mod;
ret.num[i]%=mod;ret.len=max(ret.len,i);
}
return ret;
} ExtInt operator *(ExtInt a,ExtInt b){
ExtInt ret();
for(int i=;i<=a.len;i++){
for(int j=,in=;j<=b.len||in;j++){
ret.num[i+j-]+=a[i]*b[j]+in;in=ret[i+j-]/mod;
ret.num[i+j-]%=mod;ret.len=max(ret.len,i+j-);
}
while(!ret[ret.len])
ret.num[ret.len--]=;
ret.len=max(ret.len,);
}
return ret;
} ExtInt operator ^(ExtInt a,int k){
ExtInt ret();
while(k){
if(k&)ret=ret*a;
k>>=;a=a*a;
}
return ret;
} ExtInt operator /(ExtInt a,int k){
for(int i=a.len,tot=;i>=;i--){
tot=tot*+a[i];
a.num[i]=tot/k;
tot%=k;
}
while(!a[a.len])
a.num[a.len--]=;
return a;
} int GCD(int a,int b){
return b?GCD(b,a%b):a;
} int main(){
scanf("%d",&n);
Linear_Shaker();
ExtInt ans();
for(int d=;d<=n;d++)
if(n%d==){
ExtInt x();
ans=ans+(x^d)*phi[n/d];
}
ans=ans/n;
ans.Prf();
return ;
}

数学计数原理(Pólya,高精度):SGU 294 He's Circles的更多相关文章

  1. 数学计数原理(Pólya):POJ 1286 Necklace of Beads

    Necklace of Beads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7763   Accepted: 3247 ...

  2. SGU 294 He's Circles

    题意:一个项链有n个珠子,每个珠子为黑色或白色.问有多少种不同的项链? 注意,n的数量十分大,因此,我们枚举i(1<=i<=n),令L=n/i,求出L的欧拉函数,则这些数和L互质,因此gc ...

  3. STM32F4_TIM基本延时(计数原理)

    Ⅰ.概述 STM32的TIM定时器分为三类:基本定时器.通用定时器和高级定时器.从分类来看就知道STM32的定时器功能是非常强大的,但是,功能强大了,软件配置定时器就相对复杂多了.很多初学者甚至工作了 ...

  4. Luogu 1351 NOIP 2014 联合权值(贪心,计数原理)

    Luogu 1351 NOIP 2014 联合权值(贪心,计数原理) Description 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi, ...

  5. 组合数学(Pólya计数原理):UvaOJ 10601 Cubes

    Cubes You are given 12 rods of equal length. Each of them is colored in certain color. Your task is ...

  6. 数学(GCD,计数原理)HDU 5656 CA Loves GCD

    CA Loves GCD Accepts: 135 Submissions: 586 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 2621 ...

  7. HDU 5441 Travel (并查集+数学+计数)

    题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u ...

  8. 【洛谷】【计数原理+Floyed】P1037 产生数

    [题目描述:] 给出一个整数 n \((n<10^{30})\) 和 k 个变换规则\((k≤15)\) . 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如: n=234 .有 ...

  9. Codeforces 582C. Superior Periodic Subarrays(数学+计数)

    首先可以把 i mod n=j mod n的看成是同一类,i mod s=j mod s的也看成是同一类,也就是i mod gcd(s,n)的是同一类,很好理解,但是不会数学证明...大概可以想成数轴 ...

随机推荐

  1. Markdown写接口文档,自动添加TOC

    上回说到,用Impress.js代替PPT来做项目展示.这回换Markdown来做接口文档好了.(不敢说代替Word,只能说个人感觉更为方便)当然,还要辅之以Git,来方便版本管理. Markdown ...

  2. php 多维数组转换

    把字符类型转换成时间类型的,先用foreach遍历出来时间,在通过时间函数转换成时间格式; 例子: <?phpecho "<pre>";$lsrfield = a ...

  3. 第五篇:python高级之面向对象高级

    python高级之面向对象高级   python高级之面向对象高级 本节内容 成员修饰符 特殊成员 类与对象 异常处理 反射/自省 单例模式 1.成员修饰符 python的类中只有私有成员和公有成员两 ...

  4. winform(C#)拖拽实现获得文件路径

    设置Form的AllowDrop为true  private void Form1_DragDrop(object sender, DragEventArgs e)        {          ...

  5. UOJ222 NOI2016 区间 线段树+FIFO队列

    首先将区间按长度排序后离散化端点(这里的“长度”指的是离散化之前区间的实际长度) 然后模拟一个队列,区间按排好的顺序依次进入,直到某个点被覆盖了M次.之后依次出队,直到所有点都被覆盖小于M次 修改和询 ...

  6. POJ刷题记录 (。・`ω´・)(Progress:6/50)

    1743:前后作差可以转化成不可重叠最长公共字串问题,运用后缀数组解决(参考罗穗骞神犇的论文) #include <cstdio> #include <cstring> #in ...

  7. 狗狗40题~(Volume B)

    H - Sorting Slides 应该是个二分匹配的模板题的,但我还不会写 = = 其实数据规模很小,就用贪心的方法就水过了(没加vis判冲突wa了几发,从此开始艰难的没有1A 的生活) #inc ...

  8. SQL2012之FileTable与C#的联合应用

    关于FileTable是什么,请猛击如下链接:http://technet.microsoft.com/zh-cn/library/ff929144(v=SQL.110).aspx:如您已知道,请跳过 ...

  9. 五分钟看懂js关键字this

    this是js里面很常用的关键字,而灵活的js也赋予了这个关键字无穷的生命力,相信你也有被它糊弄的时候,我总结了一个6字原则,大部分场合都能清醒分辨this到底指向who,跟大家分享一下,欢迎指正. ...

  10. HTML5拖放API

    拖放事件事件提供了拖放可以控制几乎所有方面的拖放操作.棘手的部分是确定每个事件触发:在拖项目火:别人火下降的目标.拖动项时,以下事件(按照这个顺序): 拖曳开始拖dragend此刻你把鼠标按钮和开始移 ...