zoukankan      html  css  js  c++  java
  • hdu 5868 Polya计数

    Different Circle Permutation

    Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 218    Accepted Submission(s): 106

    Problem Description
    You may not know this but it's a fact that Xinghai Square is Asia's largest city square. It is located in Dalian and, of course, a landmark of the city. It's an ideal place for outing any time of the year. And now:
      
      There are N children from a nearby primary school flying kites with a teacher. When they have a rest at noon, part of them (maybe none) sit around the circle flower beds. The angle between any two of them relative to the center of the circle is always a multiple of 2πN but always not 2πN.
      
      Now, the teacher raises a question: How many different ways there are to arrange students sitting around the flower beds according to the rule stated above. To simplify the problem, every student is seen as the same. And to make the answer looks not so great, the teacher adds another specification: two ways are considered the same if they coincide after rotating.
     
    Input
    There are T tests (T50). Each test contains one integer N1N1000000000 (109). Process till the end of input.
     
    Output
    For each test, output the answer mod 1000000007 (109+7) in one line.
     
    Sample Input
    4 7 10
     
    Sample Output
    3 5 15
     
    Source
    /*
    hdu 5868 Polya计数
    
    problem:
    给你n个人,围绕成圆坐下,任意两人之间的距离必需是2pi/n的倍数.求旋转等效的情况下有多少种方案数
    
    solve:
    相当于给你n个间距为2pi/n的点,然后进行黑白染色,黑点不能相邻. (黑点表示坐人)
    考虑Polya计数的话,需要枚举长度且得到长度为i的方案数.
    找规律可以发现 f[n] = f[n-1] + f[n-2],用矩阵快速幂可以快速求出
    
    hhh-2016-09-20 19:26:01
    */
    #pragma comment(linker,"/STACK:124000000,124000000")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <map>
    #define lson  i<<1
    #define rson  i<<1|1
    #define ll long long
    #define clr(a,b) memset(a,b,sizeof(a))
    #define key_val ch[ch[root][1]][0]
    using namespace std;
    const int maxn = 200100;
    const int inf = 0x3f3f3f3f;
    const ll mod = 1e9 + 7;
    struct Matrix
    {
        ll ma[2][2];
        Matrix()
        {
            memset(ma,0,sizeof(ma));
        }
    };
    
    Matrix mat;
    Matrix from;
    
    Matrix Mul(Matrix a,Matrix b)
    {
        Matrix c;
        for(int i = 0; i < 2; i++)
        {
            for(int j = 0; j < 2; j++)
            {
                c.ma[i][j] = 0;
                for(int k = 0; k < 2; k++)
                {
                    c.ma[i][j] = c.ma[i][j] + a.ma[i][k]*b.ma[k][j] % mod;
                    c.ma[i][j] %= mod;
                }
            }
        }
        return c;
    }
    
    Matrix Pow(int n)
    {
        Matrix cnt;
        Matrix t = mat;
        memset(cnt.ma,0,sizeof(cnt.ma));
        for(int i = 0; i < 2; i++)
            cnt.ma[i][i] = 1;
        while(n)
        {
            if(n & 1)
                cnt = Mul(cnt,t);
            t = Mul(t,t);
            n >>= 1;
        }
        return cnt;
    }
    
    void init()
    {
    mat.ma[0][0] = 1,mat.ma[0][1] = 1,mat.ma[1][0] = 1,mat.ma[1][1] = 0;
        from.ma[0][0] = 3,from.ma[1][0] = 1,from.ma[0][1] = 0,from.ma[1][1] = 0;
    }
    int n;
    ll f(int i)
    {
        if(i == 1)
             return 1;
        if(i == 2)
            return 3;
        Matrix t = Mul(Pow(i-2),from);
        return t.ma[0][0];
    }
    
    ll pow_mod(ll a,ll n)
    {
        ll ret = 1;
        a %= mod;
        while(n)
        {
            if(n & 1) ret = ret*a%mod;
            a = a*a%mod;
            n >>= 1;
        }
        return ret%mod;
    }
    
    ll euler(ll n)
    {
        ll ans = n;
        ll i;
        for (i = 2; i*i <= n; i++)
        {
            if (n%i == 0)
            {
                while (n%i == 0)
                    n /= i;
                ans = ans/i*(i-1) ;
            }
        }
        if (n != 1)
            ans = ans/n*(n-1);
        return ans;
    }
    
    
    void cal(int n)
    {
        if(n == 1)
        {
            printf("2
    ");
            return ;
        }
        ll ans = 0;
        for(int i = 1; i*i <= n; i++)
        {
            if(n % i == 0)
            {
                ans = (ans + f(i)*euler(n/i)%mod)%mod;
                if( i*i != n)
                {
                    ans = (ans + f(n/i)*euler(i)%mod)%mod;
                }
            }
        }
    //    cout <<ans <<endl;
        ans = ans*pow_mod(n,mod-2)%mod;
        printf("%I64d
    ",ans);
    }
    
    int main()
    {
        init();
    //    for(int i =1 ;i <= 10;i++)
    //        cout << f(i) <<endl;
    //    for(int i =1 ;i <= 10;i++)
    //        cout << euler(i) <<endl;
        while(scanf("%d",&n) != EOF)
        {
            init();
            cal(n);
        }
    }
    

      

  • 相关阅读:
    当初为蜂巢样式实验过的方法
    在看 jquery 源码中发现的一些优化方向
    我终于有案例库啦(github 提供的)
    学习笔记(五)
    试坑不完美的 clip-path (我说的 CSS 的那个)
    解决安卓机在微信上播放视频有广告问题
    requestAnimationFrame 的实验性实践
    学习笔记(四)
    ajax
    php 增删改查---增
  • 原文地址:https://www.cnblogs.com/Przz/p/5890119.html
Copyright © 2011-2022 走看看