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. 利用switch语句进行多选一判断。

    <!doctype html> <meta http-equiv="content-type" content="text/html" cha ...

  2. CentOS 6.7 编译安装Nginx 1.8.0

    1.配置编译环境 yum update && yum upgrade yum groupinstall "Development Tools" 或者 yum ins ...

  3. [Redis] C#中使用redis

    C#中使用redis 首先打开Visual Studio建立一个简单的控制台应用程序,我这里暂时使用的VS2013的版本. 然后通过Nuget进行安装Redis常用组件ServiceStack.Red ...

  4. linux的grep命令

    参考文档如下: linux grep命令 grep abb15455baeb4b23ab47540272ec47eb epps-sas.log | grep operateSettleBill exp ...

  5. copy file using FileReader/Writer.

    The code below demonstates copying file using 'FileReader' and 'FileWriter'. class CopyV2 extends Ti ...

  6. copssh加bitvise

    只是简单记录下自己在成功使用的方案: 目的:为了突破公司对网站和qq的限制 具备的条件:一台云服务器.Copssh_4.1.0.bitvise ssh client 4.62.公司电脑客户端 一.首先 ...

  7. google的西联汇款可以使用工行代收

  8. corejava_chap02

    //单行注释  --不能用在一行代码的中间/**/多行注释 --任何地方/** */文档注释  文档注释用在:package.class.member variables.member method. ...

  9. SGU 197.Nice Patterns Strike Back

    时间限制:0.5s 空间限制:6M 题意: 给出长n(n<=10^100)和宽m(m<=5)的地面,铺上黑色和白色的地板,使得没有任意一个2*2大小的地面铺同种颜色的方案数是多少. Sol ...

  10. placeholder调整颜色

    placeholder需要设定以下样式: ::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeh ...