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
  • 相关阅读:
    正则表达式-汉字的匹配方法
    python 正则匹配中文(unicode)(转)
    Notepad++ 快捷键 大全
    gvim 编辑器配置
    gvim代码补全
    UNICODE,GBK,UTF-8区别
    AJAX
    day 75 中间件
    Cookie和Session 装饰器的修复技术
    必知必会13条 单表查询之双下划线 ForeignKey操作 ManyToManyField 聚合分组
  • 原文地址:https://www.cnblogs.com/hate13/p/4465962.html
Copyright © 2011-2022 走看看