数学计数原理(Pólya,高精度):SGU 294 He's Circles

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。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 const int maxn=200010;
  6 int n,tot;
  7 int phi[maxn],pri[maxn];
  8
  9 void Linear_Shaker(){
 10     phi[1]=1;
 11     for(int i=2;i<=n;i++){
 12         if(!phi[i]){
 13             phi[i]=i-1;
 14             pri[++tot]=i;
 15         }
 16         for(int j=1;j<=n;j++){
 17             if(i*pri[j]>n)break;
 18             if(i%pri[j]!=0)
 19                 phi[i*pri[j]]=phi[i]*(pri[j]-1);
 20             else{
 21                 phi[i*pri[j]]=phi[i]*pri[j];
 22                 break;
 23             }
 24         }
 25     }
 26 }
 27
 28 int POW[4]={1,10,100,1000};
 29 const int mod=10000;
 30 struct ExtInt{
 31     int num[20010],len;
 32     ExtInt(int x){len=0;
 33         memset(num,0,sizeof(num));
 34         do{
 35             num[++len]=x%mod;
 36             x/=mod;
 37         }while(x);
 38     }
 39
 40     void Scf(){
 41         char s[10010];scanf("%s",s+1);
 42         memset(num,0,sizeof(num));len=1;
 43         for(int i=strlen(s+1),cnt=0;i>=1;i--){
 44             num[len]+=POW[cnt++]*(s[i]-‘0‘);
 45             if(cnt==4)cnt=0,len+=1;
 46         }
 47     }
 48
 49     int operator [](int x){
 50         return num[x];
 51     }
 52
 53     void Prf(){
 54         printf("%d",num[len]);
 55         for(int i=len-1;i>=1;i--)
 56             printf("%04d",num[i]);
 57         printf("\n");
 58     }
 59 };
 60
 61 ExtInt operator +(ExtInt a,int b){
 62     ExtInt ret(0);
 63     ret.len=a.len;
 64     for(int i=1,in=0;i<=ret.len||in;i++){
 65         ret.num[i]=a[i]+b+in;in=ret[i]/mod;
 66         ret.num[i]%=mod;ret.len=max(ret.len,i);
 67     }
 68     return ret;
 69 }
 70
 71 ExtInt operator +(ExtInt a,ExtInt b){
 72     ExtInt ret(0);
 73     ret.len=max(a.len,b.len);
 74     for(int i=1,in=0;i<=ret.len||in;i++){
 75         ret.num[i]=a[i]+b[i]+in;in=ret[i]/mod;
 76         ret.num[i]%=mod;ret.len=max(ret.len,i);
 77     }
 78     return ret;
 79 }
 80
 81 ExtInt operator *(ExtInt a,ExtInt b){
 82     ExtInt ret(0);
 83     for(int i=1;i<=a.len;i++){
 84         for(int j=1,in=0;j<=b.len||in;j++){
 85             ret.num[i+j-1]+=a[i]*b[j]+in;in=ret[i+j-1]/mod;
 86             ret.num[i+j-1]%=mod;ret.len=max(ret.len,i+j-1);
 87         }
 88         while(!ret[ret.len])
 89             ret.num[ret.len--]=0;
 90         ret.len=max(ret.len,1);
 91     }
 92     return ret;
 93 }
 94
 95 ExtInt operator ^(ExtInt a,int k){
 96     ExtInt ret(1);
 97     while(k){
 98         if(k&1)ret=ret*a;
 99         k>>=1;a=a*a;
100     }
101     return ret;
102 }
103
104 ExtInt operator /(ExtInt a,int k){
105     for(int i=a.len,tot=0;i>=1;i--){
106         tot=tot*10000+a[i];
107         a.num[i]=tot/k;
108         tot%=k;
109     }
110     while(!a[a.len])
111         a.num[a.len--]=0;
112     return a;
113 }
114
115 int GCD(int a,int b){
116     return b?GCD(b,a%b):a;
117 }
118
119 int main(){
120     scanf("%d",&n);
121     Linear_Shaker();
122     ExtInt ans(0);
123     for(int d=1;d<=n;d++)
124         if(n%d==0){
125             ExtInt x(2);
126             ans=ans+(x^d)*phi[n/d];
127         }
128     ans=ans/n;
129     ans.Prf();
130     return 0;
131 }

数学计数原理(Pólya,高精度):SGU 294 He's Circles

时间: 2024-10-03 13:46:28

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

SGU 294 He&#39;s Circles

题意:一个项链有n个珠子,每个珠子为黑色或白色.问有多少种不同的项链? 注意,n的数量十分大,因此,我们枚举i(1<=i<=n),令L=n/i,求出L的欧拉函数,则这些数和L互质,因此gcd(k,n)=i的k一共有L的欧拉函数个,这是一个很聪明的转换方式,而且这题需要高精度.最终答案就是Σ(2^i*K)/n,K为(n/i)的欧拉函数. 代码:太长不敢打,怕改个一天都改不出来. SGU 294 He's Circles

数学计数原理(P&#243;lya):POJ 1286 Necklace of Beads

Necklace of Beads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7763   Accepted: 3247 Description Beads of red, blue or green colors are connected together into a circular necklace of n beads ( n < 24 ). If the repetitions that are pro

[从头学数学] 第195节 计数原理

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第五转的修炼. 这次要研究的是[计数原理]. 正剧开始: 星历2016年04月25日 10:22:16, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[计数原理]. <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,10,1,1.5); config.graphPaper2D(0, 0

【组合数学】计数原理

计数原理     ①抽屉原理               有N个抽屉,N+1个苹果,那么至少有一个抽屉有两个或两个以上的苹果.               有N个抽屉,N-1个苹果,那么至少有一个抽屉没有苹果.       ②加法原理         如果A类物品有a个,B类物品有b个,那么A类物品或B类物品共有a+b个(没有性质相同的情况下)       ③乘法原理         如果A有a中发生方式,B有b中发生方式,那么发生事件A与B有a*b中发生方式.       ④容斥原理 ∪=并

专题——计数原理

由于最近在研究数论,所以这期为大家带来一个数论中的专题--计数原理,下面我们来看四个概念: 一.配对原理: 对于集合A.B,如果存在一个一一映射,f:A→B,则|A|=|B|,假如我们很难计算A的值,不如转变方法,先计算B的值,再根据一一映射反推A,这时就需要找到这样一个易于计算的B,这需要很高的技巧.二.容斥原理: <1>容斥原理 把集合A分成子集A1,A2,A3,-,Am,即:A=A1∪A2∪A3-∪Am ,简单的来说,要求的集合是等于全集减去所有子集相交的重复的部分. <2>

STM32F4_TIM基本延时(计数原理)

Ⅰ.概述 STM32的TIM定时器分为三类:基本定时器.通用定时器和高级定时器.从分类来看就知道STM32的定时器功能是非常强大的,但是,功能强大了,软件配置定时器就相对复杂多了.很多初学者甚至工作了一段时间的人都不知道STM32最基本的计数原理. 虽然STM32定时器功能强大,也分了三类,但他们最基本的计数部分原理都是一样的,也就是我们常常使用的延时(或定时)多少us.ms等. 接下来我会讲述关于STM32最基本的计数原理,详细讲述如何做到(配置)计数1us的延时,并提供实例代码供大家参考学习

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

CA Loves GCD Accepts: 135 Submissions: 586 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) 问题描述 CA喜欢是一个热爱党和人民的优秀同♂志,所以他也非常喜欢GCD(请在输入法中输入GCD得到CA喜欢GCD的原因). 现在他有N个不同的数,每次他会从中选出若干个(至少一个数),求出所有数的GCD然后放回去. 为了使自己不会无聊,CA会把每

组合数学(P&#243;lya计数原理):UvaOJ 10601 Cubes

Cubes You are given 12 rods of equal length. Each of them is colored in certain color. Your task is to determine in how many different ways one can construct a cube using these rods as edges. Two cubes are considered equal if one of them could be rot

无标号树的计数原理(组合计数,背包问题,隔板法,树的重心)

闲话 一个计数问题入门级选手来搞这种东西 最初的动力来自高一化学课有机物(滑稽).<同步导练>出了个这样的选择题. 一个结构极其庞大的烷烃(二十几个碳原子),求它的主链长度. 这不是个求树的直径的裸题么?!OI选手扫两眼就出来了,然而别的同学费劲心思找完了还是错的. 于是第一次在常规课中体验到作为OIer的优越感...... 又是一节课,芙蓉姐开始要我们画己烷.庚烷的同分异构体?! 这不是等于要求节点数为\(n\),点度数不超过\(4\)的无标号的无根树个数吗?没见过,但还是有一点DP思想,蒟