POJ 2888 Magic Bracelet(Burnside引理+欧拉函数+矩阵快速幂+逆元)
来源:互联网 发布:华为防火墙开放端口 编辑:程序博客网 时间:2024/06/05 15:31
Description
Ginny’s birthday is coming soon. Harry Potter is preparing a birthday present for his new girlfriend. The present is a magic bracelet which consists of n magic beads. The are m kinds of different magic beads. Each kind of beads has its unique characteristic. Stringing many beads together a beautiful circular magic bracelet will be made. As Harry Potter’s friend Hermione has pointed out, beads of certain pairs of kinds will interact with each other and explode, Harry Potter must be very careful to make sure that beads of these pairs are not stringed next to each other.
There infinite beads of each kind. How many different bracelets can Harry make if repetitions produced by rotation around the center of the bracelet are neglected? Find the answer taken modulo 9973.
Input
The first line of the input contains the number of test cases.
Each test cases starts with a line containing three integers n (1 ≤ n ≤ 109, gcd(n, 9973) = 1), m (1 ≤ m ≤ 10), k (1 ≤ k ≤ m(m − 1) ⁄ 2). The next k lines each contain two integers a and b (1 ≤ a, b ≤ m), indicating beads of kind a cannot be stringed to beads of kind b.
Output
Output the answer of each test case on a separate line.
Sample Input
43 2 03 2 11 23 2 21 11 23 2 31 11 22 2
Sample Output
4210
Source
[Submit] [Go Back] [Status] [Discuss]
Home Page Go Back To top
题意:n个珠子组成项链,m种颜色为其染色,然而有k种关系限制。即颜色x和颜色y不能相邻。
题解:假如没有颜色不相邻限制的话就是polya定理计数模板题了,有了限制的话我们就不能用polya定理了。
呢该怎么办呢?用了半天容斥原理发现根本不对。。看了题解,真的是神题。。。。。
既然polya定理不适用,呢我们就要考虑Burnside引理了(换着用?)
我们首先回顾一下burnside引理:一个本质不同的组合数等于所有置换下不动点的个数之和除以置换种类数。
因为这题只有旋转,并且项链的旋转是有规律的,不难发现,每一个循环节中相邻的珠子的距离是相同的。
可是这和解这道题有关系吗?先别着急,我们往下走,此时我们可以求出同一个循环节中相邻珠子的距离一定为
gcd(i,n),假如我们从任意一个珠子开始顺时针数起,这gcd(n,i)个珠子一定在不同循环节中。还是呢句话,这和这道题有关系吗? 说实话,不看题解我是真的无从下手,题解也是看了将近3个小时。。越看越迷。。。
但其实想到这里问题已经解决了不是吗?根据burnside引理,不就是求长度为gcd(i,n)的珠子的染色数嘛。。
剩下的问题就好办了,对于gcd(i,n),我们可以用欧拉函数降低复杂度,然后对于合法染色数,我们可以考虑用矩阵优化,因为最后要除以n,而n又很大,我们可以让其乘上n的逆元即可。。。
#include<set> #include<map> #include<stack> #include<queue> #include<vector> #include<string> #include<time.h> #include<math.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> #include<functional> using namespace std; #define ll long long #define inf 1000000000 #define mod 9973 #define maxn 50005 #define lowbit(x) (x&-x) #define eps 1e-9 int a[maxn]={1,1},b[maxn],cnt; struct node{ll x[15][15];}aa;void init(){ll i,j;for(i=2;i<maxn;i++) { if(a[i]) continue; b[++cnt]=i; for(j=i*i;j>0 && j<maxn;j+=i) a[j]=1; } }ll q(ll x,ll y) { ll res=1; while(y) { if(y%2) res=res*x%mod; x=x*x%mod; y/=2; } return res; } node q2(node a,node b,ll m){ll i,j,k;node c;for(i=1;i<=m;i++)for(j=1;j<=m;j++){c.x[i][j]=0;for(k=1;k<=m;k++)c.x[i][j]=c.x[i][j]+a.x[i][k]*b.x[k][j];c.x[i][j]%=mod;}return c;}node q1(node a,ll y,ll m){node b;int i,j;for(i=1;i<=m;i++)for(j=1;j<=m;j++){if(i==j)b.x[i][j]=1;elseb.x[i][j]=0;}while(y){if(y%2)b=q2(b,a,m);a=q2(a,a,m);y/=2;}return b;}ll ol(ll x) { ll i,res=x; for(i=1;i<=cnt && b[i]*b[i]<=x;i++) { if(x%b[i]==0) { res=res-res/b[i]; while(x%b[i]==0) x/=b[i]; } } if(x>1) res=res-res/x; return res; } ll work(node a,ll m){ll ans=0;int i;for(i=1;i<=m;i++)ans=(ans+a.x[i][i])%mod;return ans;}int main(void) { int t;init(); ll n,m,i,j,k,x,y; scanf("%d",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&k);for(i=1;i<=m;i++)for(j=1;j<=m;j++)aa.x[i][j]=1;for(i=1;i<=k;i++){scanf("%lld%lld",&x,&y);aa.x[x][y]=aa.x[y][x]=0;}ll ans=0;for(i=1;i*i<=n;i++){if(n%i==0){node tmp;tmp=q1(aa,i,m);ans=(ans+ol(n/i)%mod*work(tmp,m)%mod)%mod;if(i*i==n)break;tmp=q1(aa,n/i,m);ans=(ans+ol(i)%mod*work(tmp,m)%mod)%mod;}}ans=(ans*q(n,mod-2))%mod;printf("%lld\n",ans); } return 0; }
- POJ 2888 Magic Bracelet(Burnside引理+欧拉函数+矩阵快速幂+逆元)
- POJ 2888 Magic Bracelet(Polya计数+dp+矩阵快速幂+欧拉函数+乘法逆元)
- Poj 2888 & Hoj 2722 Magic Bracelet (有限制的Burnside 矩阵性质 欧拉函数)
- POJ 2888 Magic Bracelet (Burnside , 矩阵幂 )
- poj 2888 Magic Bracelet 置换(Burnside引理)+矩阵
- POJ 2888 Magic Bracelet (Polya+欧拉函数+矩阵乘法)
- hdu 5868 矩阵快速幂+burnside引理 +欧拉函数+乘法逆元
- POJ 2888 Magic Bracelet (有限制的Burnside引理)
- POJ 2888 Magic Bracelet(polya+矩阵快速幂)
- POJ-2888-Magic Bracelet-Burnside&&polay计数
- 【POJ2888】Magic Bracelet-Burnside引理+数论+DP矩阵优化
- POJ 2888 Magic Bracelet (经典Polya+矩阵)
- poj 2888 Magic Bracelet (矩阵乘法+置换)
- poj 2888 Magic Bracelet (polya,矩阵)
- poj 2888 Magic Bracelet
- POJ 2888 Magic Bracelet
- poj-2888 Magic Bracelet
- POJ 2888 Magic Bracelet
- Python 基础
- 将博客搬至CSDN
- oracle中pl/sql编程(一):
- RCNN学习笔记(0)-RCNN->SPPnet->Fast RCNN->Faster RCNN
- 深度学习中的概率统计、数值优化算法
- POJ 2888 Magic Bracelet(Burnside引理+欧拉函数+矩阵快速幂+逆元)
- 【广告算法工程师入门 16】机制设计-最优拍卖机制设计
- maven依赖的原则
- 【20171002】python_语言设计(3)函数
- 二、CSS【Cascading Style Sheets层叠样式表】
- hihocoder-1393 二分图的多重匹配(网络流做法)
- 操作系统--进程之fork
- CodeForces
- 特征选择