博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5868 Different Circle Permutation
阅读量:5162 次
发布时间:2019-06-13

本文共 3213 字,大约阅读时间需要 10 分钟。

原题链接为:

题意为一群孩子按圈排座位。可以看成是给一个项链染色,有两种颜色0和1,同时相邻处不能都染1,若两种染色方案旋转后相同则视为同一种方案。

从题意可以明显的看出,这是一道考察Burnside引理的数论题。
首先,变换方式只有旋转,可以得出,答案应为\( \frac{1}{n}\sum_{i=1}^{n}f(gcd(i,n)) \)。其中f(x)为表示长度为x的一个循环节的染色方案数。

在本题中,考虑最后一个涂1时,则f(x)=f(x-2),最后一个涂0时,则f(x)=f(x-1)。所以f(x)=f(x-1)+f(x+2)。换言之,斐波那契数列。但是同时必须注意的一点是,f(1)=1。因为在循环节长度为1时,若涂1则项链每个环都是1,不符合题意。所以f(1)=1,f(2)=3,f(3)=4,f(4)=7…本人的做法是将f(0)设为2。同时需要注意的一点是,当n=1是,需要特判。对于斐波那契数列,理所当然的想到要使用矩阵快速幂。

同时,考虑到n的数值非常大,直接使用\( \frac{1}{n}\sum_{i=1}^{n}f(gcd(i,n)) \)计算是不可能的。所以对此式进一步简化为\(\sum _{d \mid n} f(gcd(d,n)) * \phi(n/d)\),其中\( \phi() \)函数,即欧拉函数直接计算即可。

而对于\( \frac{1}{n} \),因为10^9+7是质数,直接计算逆元即可。

下面是AC的代码:

1 #include"cstdio"  2 #include"cstring"  3 #include"string"  4 #include"cstdlib"  5 #include"vector"  6 #include"set"  7 #include"map"  8 #include"cmath"  9 using namespace std; 10 typedef long long LL; 11  12 const LL MOD=1000000007; 13 LL gcd(LL a, LL b) 14 { 15     if(b==0) return a; 16 return gcd(b,a%b); 17 } 18 LL powMod(LL x,LL n,LL mod) 19 { 20 LL res=1; 21 while(n>0) 22  { 23 if(n&1) res=res*x % mod; 24 x=x*x % mod; 25 n>>=1; 26  } 27 return res; 28 } 29 const LL MAXR=100; 30 const LL MAXC=100; 31 struct Matrix 32 { 33  LL m[MAXR][MAXC]; 34  LL r,c; 35  Matrix() 36  { 37 r=0,c=0; 38 memset(m,0,sizeof(m)); 39  } 40 }; 41 //若不能相乘,返回空矩阵 42 Matrix operator * (const Matrix &a,const Matrix &b) 43 { 44  Matrix ans; 45 LL r=a.r,c=b.c,x=0; 46 if(a.c!=b.r) return Matrix(); 47 x=a.c; 48 ans.r=a.r; 49 ans.c=b.c; 50 for (LL i=1; i<=r; i++) 51 for (LL j=1; j<=c; j++) 52  { 53 ans.m[i][j]=0; 54 for (LL k=1; k<=x; k++) 55 ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]) % MOD; 56  } 57 return ans; 58 } 59 //若不能乘方,返回空矩阵 60 Matrix operator ^ (Matrix &base,LL pow) 61 { 62 if(base.r!=base.c) return Matrix(); 63 LL x=base.r; 64  Matrix ans; 65 ans.r=ans.c=x; 66 for (LL i=1; i<=x; i++) ans.m[i][i]=1; 67 while (pow) 68  { 69 if (pow&1) ans=ans*base; 70 base=base*base; 71 pow>>=1; 72  } 73 return ans; 74 } 75 LL eularPhi(LL n) 76 { 77 LL res=n; 78 for(LL i=2;i*i<=n;i++) 79  { 80 if(n%i==0) 81  { 82 res=res/i*(i-1); 83 for(;n%i==0;n/=i); 84  } 85  } 86 if(n!=1) res=res/n*(n-1); 87 return res; 88 } 89 //拓展欧几里得算法 90 //求ax+by=gcd(a,b)的一组解 91 //其他解为x=x0+kb',y=y0-ka' 92 //a'=a/gcd(a,b),b'=b/gcd(a,b) 93 LL extgcd(LL a,LL b,LL &x,LL &y) 94 { 95 LL d=a; 96 if(b!=0) 97  { 98 d=extgcd(b,a%b,y,x); 99 y-=(a/b)*x; 100  } 101 else { x=1; y=0; } 102 return d; 103 } 104 //求逆元 105 //a和m应该互质 106 LL modInverse(LL a,LL m) 107 { 108  LL x,y; 109  extgcd(a,m,x,y); 110 return (m+x%m)%m; 111 } 112 LL f(LL x) 113 { 114  Matrix a,b; 115 a.r=1; a.c=2; a.m[1][1]=2; a.m[1][2]=1; 116 b.r=2; b.c=2; b.m[1][1]=0; b.m[1][2]=b.m[2][1]=b.m[2][2]=1; 117 return (a*(b^x)).m[1][1]; 118 } 119 int main() 120 { 121 #ifdef LOCAL 122 freopen("in.txt","r",stdin); 123 #endif 124  LL n; 125 while(scanf("%lld",&n)!=EOF) 126  { 127 if(n==1) 128  { 129 printf("%d\n",2); 130 continue; 131  } 132 LL ans=0; 133 for(LL i=1;i<=sqrt(n);i++) 134 if(n%i==0) 135  { 136 LL d=i; 137 ans=(ans+f(d)*eularPhi(n/d))%MOD; 138 d=n/i; 139 if(d*d==n) continue; 140 ans=(ans+f(d)*eularPhi(n/d))%MOD; 141  } 142 printf("%lld\n",ans*modInverse(n,MOD)%MOD); 143  } 144 return 0; 145 }

 

转载于:https://www.cnblogs.com/zarth/p/6363409.html

你可能感兴趣的文章
生成对抗网络(Generative Adversarial Network)阅读笔记
查看>>
GIT原理和常用命令速成
查看>>
Jmeter之集合点与关联
查看>>
springboot整合webservice
查看>>
字符串匹配KMP算法详解
查看>>
单词查找排序输出
查看>>
TCP三次握手和四次挥手及用户访问网页流程
查看>>
echo常用操作
查看>>
算法笔记
查看>>
LeetCode 237. Delete Node in a Linked List 删除链表结点(只给定要删除的结点) C++/Java...
查看>>
LCA倍增模板
查看>>
EMS-Demo 雇员管理系统演示
查看>>
软件工程第二次作业——心得体会(结对编程)
查看>>
ORA-12560: TNS: 协议适配器错误 ORA-12154: TNS: 无法解析指定的连接标识符
查看>>
读书印记 - 《菊与刀》
查看>>
第一个小demo: spring boot + mybatis + thymeleaf
查看>>
mysql获取字段信息
查看>>
Tomcat 网站部署(三)
查看>>
JS实现全选与取消 Jquery判断checkbox是否被选中
查看>>
如果重新设计网络,有没有可能合并IP地址跟MAC地址?
查看>>