zoukankan      html  css  js  c++  java
  • hdu 5868:Different Circle Permutation 【Polya计数】

    似乎是比较基础的一道用到polya定理的题,为了这道题扣了半天组合数学和数论。

    等价的题意:可以当成是给正n边形的顶点染色,旋转同构,两种颜色,假设是红蓝,相邻顶点不能同时为蓝。

    大概思路:在不考虑旋转同构的情况下,正n边形有fib(n+1)+fib(n-1)种染色方法(n==1特判),然后后面就是套公式了,涉及到要用欧拉定理优化,不然会T。(理论的东西看下组合数学书中polya计数部分,及数论书中欧拉函数部分中 n的约数的欧拉函数,感觉看博客不如系统的看看书,再结合一下网上一些比较基础的polya题来理解。)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5868

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    LL Eular(LL n)
    {
        LL ret=n;
        for(LL i=2; i*i<= n; i++)
        {
            if(n%i==0)
            {
                ret-=ret/i;
                while(n%i==0) n/= i;
            }
        }
        if(n>1) ret-=ret/n;
        return ret;
    }
    LL qpow(LL n,LL k)
    {
        LL res=1;
        for(; k; k>>=1)
        {
            if(k&1) res=res*n%mod;
            n=n*n%mod;
        }
        return res;
    }
    LL inv(LL x)
    {
        return qpow(x,mod-2);
    }
    const LL N=2;
    struct Mat
    {
        LL mat[N][N];
    };
    Mat Mut(Mat a,Mat b)
    {
        LL i,j,k;
        Mat c;
        memset(c.mat,0,sizeof(c.mat));
        for(k=0; k<N; k++)
        {
            for(i=0; i<N; i++)
            {
                if(a.mat[i][k])
                    for(j=0; j<N; j++)
                    {
                        if(b.mat[k][j])
                            c.mat[i][j]=c.mat[i][j]+a.mat[i][k]*b.mat[k][j];
                        c.mat[i][j]=c.mat[i][j]%mod;
                    }
            }
        }
        return c;
    }
    Mat Pow(Mat a,LL n)
    {
        Mat c;
        for(int i = 0; i < N; ++i)
            for(int j = 0; j < N; ++j)
                c.mat[i][j] = (i == j);
        for(; n; n>>=1)
        {
            if(n&1)  c=Mut(c,a);
            a=Mut(a,a);
        }
        return c;
    }
    LL fib(LL x)
    {
        if(x==0) return 0;
        Mat A;
        A.mat[0][0]=A.mat[0][1]=A.mat[1][0]=1;
        A.mat[1][1]=0;
        Mat A_=Pow(A,x-1);
        return A_.mat[0][0];
    }
    LL polya(LL n)
    {
        if(n==1) return 2;
        LL ans=0,i;
        for(i=1;i*i<n;i++)
        if(n%i==0)
        {
            ans=(ans+Eular(i)*(fib(n/i-1)+fib(n/i+1)))%mod;
            ans=(ans+Eular(n/i)*(fib(i-1)+fib(i+1)))%mod;
        }
        if(i*i==n) ans+=Eular(i)*(fib(i-1)+fib(i+1))%mod;
        return ans*inv(n)%mod;
    }
    int main()
    {
        LL n;
        while(cin>>n)
            cout<<polya(n)<<'
    ';
    }
  • 相关阅读:
    修改数据库的兼容级别
    如何写出安全的API接口
    最新IP地址数据库
    java 中的静态(static)代码块
    Java RTTI(类型信息)(.class 类对象)
    机器学习之决策树预测——泰坦尼克号乘客数据实例
    敏捷开发 —— TDD(测试驱动开发)
    Java 内存泄漏
    红顶商人 —— 胡雪岩
    各地特色美食与点菜的艺术
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6119497.html
Copyright © 2011-2022 走看看