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 ≤ 109gcd(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 ≤ ab ≤ m), indicating beads of kind acannot be stringed to beads of kind b.

Output

Output the answer of each test case on a separate line.

Sample Input

4
3 2 0
3 2 1
1 2
3 2 2
1 1
1 2
3 2 3
1 1
1 2
2 2

Sample Output

4
2
1
0

题意:m种珠子串成由n个珠子构成的环,并且有一些限制,比如第a种与第b种不能相邻,旋转后相同算是同一种方案,求方案数。(m<=10,n<=10^9)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int mod=9973;
int n,m;
struct Matrix
{
    int mat[12][12];
    Matrix(){  memset(mat,0,sizeof(mat));  }
    Matrix operator *(const Matrix &b)const
    {
        Matrix ret ;
        for(int i = 0;i < m;i++)
            for(int j = 0;j < m;j++)
            {
                for(int k = 0;k < m;k++)
                {
                    ret.mat[i][j] =(ret.mat[i][j] +mat[i][k]*b.mat[k][j])%mod;
                }
            }
        return ret;
    }
    Matrix operator ^(int b)const
    {
        Matrix ret,tmp ;
        for(int i = 0;i < m;i++)
        {
            for(int j = 0;j < m;j++)
                tmp.mat[i][j] = mat[i][j];
            ret.mat[i][i] = 1;
        }
        while(b)
        {
            if(b&1)ret = ret*tmp;
            tmp = tmp*tmp;
            b >>= 1;
        }
        return ret;
    }
}A,B;

long long eular(long long n)//求n欧拉函数
{
	long long ret=1,i;
	for (i=2;i*i<=n;i++)
		if (n%i==0)
		{
			n/=i,ret*=i-1;
			while (n%i==0)
				n/=i,ret*=i;
		}
		if (n>1)
			ret*=n-1;
		return ret;    //n的欧拉数
}

int Nochange(int x)//求x个元素对应的f
{
    //B = power(A,x);
    B=A^x;
    int ans = 0;
    for(int i = 0;i<m;i++)
        ans=(ans+B.mat[i][i])%mod;
    return ans;
}
//快速幂,用来求逆元
long long pow_m(long long a,long long b)
{
    long long ret = 1;
    long long tmp = a%mod;
    while(b)
    {
        if(b&1)
            ret=(ret*tmp)%mod;
        tmp=(tmp*tmp)%mod;
        b=b/2;
    }
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<m;i++)
            for(int j=0;j<m;j++)
              A.mat[i][j]=1;
        while(k--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            A.mat[a-1][b-1]=A.mat[b-1][a-1]=0;
        }
        int ans=0;
        for(int i=1; i*i<=n; i++) //枚举长度
        {
            if(n%i==0)//有长度为i的循环,就会有长度为n/i的循环;
            {
                ans=(ans+eular(i)*Nochange(n/i)%mod)%mod;
                if(i!=n/i)//枚举循环长度i,找出相应的i的个数:gcd(n,i)=n/i;
                    ans=(ans+eular(n/i)*Nochange(i)%mod)%mod;
            }
        }
        ans=ans*pow_m(n,mod-2)%mod;
        cout<<ans<<endl;
    }
    return 0;
}

















   

posted on 2015-05-04 15:31  星斗万千  阅读(109)  评论(0编辑  收藏  举报