zoukankan      html  css  js  c++  java
  • hdu 4187 Alphabet Soup

    这题的主要就是找循环节数,这里用找字符串最小覆盖来实现,也就是n-next[n],证明在这http://blog.csdn.net/fjsd155/article/details/6866991

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<iomanip>
    #include<cmath>
    #include<string>
    #include<vector>
    using namespace std;
    __int64 mod=100000007;
    int dis[360005],data[360005],next[360005];
    __int64 euler(__int64 n)
    {
        int i;
        __int64 ans=1;
        for(i=2;i*i<=n;i++)
            if(n%i==0)
            {
                ans*=i-1;
                n/=i;
                while(n%i==0)
                {
                    ans*=i;
                    n/=i;
                }
            }
        if(n>1) ans*=n-1;
        return ans%mod;
    }
    int get_next(int n)
    {
        int i=0,j=-1;
        next[0]=-1;
        while(i<n)
        {
            if(j==-1||dis[i]==dis[j])
            {
                i++;
                j++;
                next[i]=j;
            }
            else j=next[j];
        }
        i=n-j;
        if(n%i)
            return n;
        return i;
    }
    __int64 pows(__int64 a,__int64 b)
    {
        __int64 ans=1;
        a%=mod;
        while(b)
        {
            if(b&1) ans=(ans*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return ans%mod;
    }
    __int64 polya(__int64 m,__int64 n)
    {
        int i,j;
        __int64 ans=0;
        for(i=1;i*i<=n;i++)
        {
            if(n%i==0)
            {
                ans=(ans+pows(m,n/i)*euler(i)%mod)%mod;
                if(i*i!=n)
                    ans=(ans+pows(m,i)*euler(n/i)%mod)%mod;
            }
        }
        return (ans*pows(n,mod-2))%mod;
    }
    int main()
    {
        int n,i,j,k,t,m,s,p;
        while(cin>>s>>p)
        {
            if(s==-1&&p==-1) break;
            for(i=0;i<p;i++) cin>>data[i];
            sort(data,data+p);
            for(i=1;i<p;i++)
                dis[i]=data[i]-data[i-1];
            dis[0]=360000-data[p-1]+data[0];
            int len=get_next(p);
            printf("%I64d
    ",polya(pows(s,len),p/len));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C语言指针和数组
    C语言malloc、calloc函数
    33、二叉树的后序遍历序列
    进程、线程、协程
    8、字符串转整数
    51、数组中的逆序对
    49、丑数
    19、正则表达式匹配
    32、从上到下打印二叉树
    leetcode5:最长回文子串
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3203789.html
Copyright © 2011-2022 走看看