zoukankan      html  css  js  c++  java
  • [POJ 2888] Magic Bracelet

    Magic Bracelet
    Time Limit: 2000MS   Memory Limit: 131072K
    Total Submissions: 4727   Accepted: 1533

    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

    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

    Source

    POJ Monthly--2006.07.30, cuiaoxiang
     
    一定要理解Burnside定理(不知道拼对没有)、不理解一定不会做、做了不一定能完全理解
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define ll long long
    #define N 32000
    
    struct Matric
    {
        int size;
        int a[12][12];
        Matric(int s=0)
        {
            size=s;
            memset(a,0,sizeof(a));
        }
        Matric operator * (const Matric &t)
        {
            Matric res=Matric(size);
            for(int i=0;i<size;i++)
            {
                for(int k=0;k<size;k++)
                {
                    if((*this).a[i][k])
                        for(int j=0;j<size;j++)
                        {
                            res.a[i][j]+=(*this).a[i][k]*t.a[k][j];
                            if(res.a[i][j]>=9973) res.a[i][j]%=9973;
                        }
                }
            }
            return res;
        }
        Matric operator ^ (int n)
        {
            Matric ans=Matric(size);
            for(int i=0;i<size;i++) ans.a[i][i]=1;
            while(n)
            {
                if(n&1) ans=ans*(*this);
                (*this)=(*this)*(*this);
                n>>=1;
            }
            return ans;
        }
        int CalNum(int k)
        {
            Matric tmp=(*this);
            tmp=tmp^k;
            int ans=0;
            for(int i=0;i<size;i++)
            {
                ans=(ans+tmp.a[i][i])%9973;
                if(ans>=9973) ans%=9973;
            }
            return ans;
        }
    };
    int tot;
    int prime[N+10];
    bool isprime[N+10];
    int phi[N+10];
    void prime_pri()
    {
        tot=0;
        phi[1]=1;
        memset(isprime,true,sizeof(isprime));
        isprime[0]=isprime[1]=false;
        for(int i=2;i<=N;i++)
        {
            if(isprime[i])
            {
                prime[tot++]=i;
                phi[i]=i-1;
            }
            for(int j=0;j<tot;j++)
            {
                if((ll)i*prime[j]>N) break;
                isprime[i*prime[j]]=false;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else
                {
                    phi[i*prime[j]]=phi[i]*(prime[j]-1);
                }
            }
        }
    }
    int euler(int n)
    {
        if(n<=N) return phi[n];
        int ret=n;
        for(int i=0;(ll)prime[i]*prime[i]<=n;i++)
        {
            if(n%prime[i]==0)
            {
                ret-=ret/prime[i];
                while(n%prime[i]==0) n/=prime[i];
            }
        }
        if(n>1) ret-=ret/n;
        return ret;
    }
    int exgcd(int a,int b,int& x, int& y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        int d=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
    int inv(int a,int MOD)
    {
        int x,y;
        exgcd(a,MOD,x,y);
        x=(x%MOD+MOD)%MOD;
        return x;
    }
    int main()
    {
        prime_pri();
        int T;
        int n,m,k;
        int MOD=9973;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k); //n个点,m种颜色,k种限制
            Matric a=Matric(m);
            for(int i=0;i<m;i++) for(int j=0;j<m;j++) a.a[i][j]=1;
            for(int i=0;i<k;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                a.a[u-1][v-1]=a.a[v-1][u-1]=0;
            }
            int ans=0;
            for(int i=1;i*i<=n;i++)
            {
                if(n%i==0)
                {
                    if(i*i==n)
                        ans+=ans+euler(i)%MOD*a.CalNum(i);
                    else
                        ans+=euler(i)%MOD*a.CalNum(n/i)+euler(n/i)%MOD*a.CalNum(i);
                    if(ans>=9973) ans%=9973;
                }
            }
            ans=ans*inv(n,MOD)%MOD;
            printf("%d
    ",ans);
        }
        return 0;
    }
    趁着还有梦想、将AC进行到底~~~by 452181625
  • 相关阅读:
    centos svn的配置使用
    bind 的使用
    我 && yii2 (二)
    我 && yii2 (一)
    vue handsontable 插件 如何验证该行内的某项内容是否填写 !
    sass穿透 scoped 的情况下 去修改ui组件的样式
    vue 3.0 编译巨慢 结局方法
    element-ui tree树形节点 自定义图标
    element
    treeselect 表单验证解决方法
  • 原文地址:https://www.cnblogs.com/hate13/p/4465962.html
Copyright © 2011-2022 走看看