小雨淅沥的下午,PoPoQQQ爷在屠了一道题后放松心情,恰看见我把知识点上的群论标记已会。
于是,为了发扬D人的精神,PoPoQQQ爷打开了BZOJ,给我找了这么一个题,说:”这题都没做过还敢说会群论?”
……
……
征战半下午,卒。
(我好菜以后再也不敢说我会啥了T_T
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define mod 997
using namespace std;
int n,cnt,ans;
int powtwo[N],factor[N],invfac[N],num[N],val[N],gcd[N][N],inv[N];
int get_gcd(int x,int y)
{
    while(y)
    {
        int t=y;
        y=x%y;
        x=t;
    }
    return x;
}
int get_inv(int x,int y)
{
    int ret=1;
    while(y)
    {
        if(y&1)ret=(ret*x)%mod;
        x=(x*x)%mod;
        y>>=1;
    }
    return ret;
}
void init()
{
    powtwo[0]=factor[0]=invfac[0]=1;
    for(int i=1;i<=mod;i++)
    {
        factor[i]=factor[i-1]*i%mod;
    }
}
void dfs(int now_num,int left)
{
    if(left==0)
    {
        int retnow=0;
        int bot=1;
        for(int i=1;i<=cnt;i++)
        {
            retnow+=num[i]*(num[i]-1)/2*val[i]+val[i]/2*num[i];
            for(int j=i+1;j<=cnt;j++)
                retnow+=num[i]*num[j]*get_gcd(val[i],val[j]);
        }
        for(int i=1;i<=cnt;i++)
        {
            bot=(bot*get_inv(val[i],num[i])%mod*factor[num[i]])%mod; 
        } 
        bot=get_inv(bot,mod-2)*factor[n]%mod; 
        ans=(ans+get_inv(2,retnow)*bot%mod)%mod; 
    }
    if(now_num>left)return;
    dfs(now_num+1,left);
    for(int i=1;i*now_num<=left;i++)
    {
        val[++cnt]=now_num,num[cnt]=i;
        dfs(now_num+1,left-i*now_num);
        cnt--;
    }
}
int main()
{
    scanf("%d",&n);
    init();
    dfs(1,n);
    ans=ans*get_inv(factor[n],mod-2)%mod;
    printf("%d\n",ans);
} 版权声明:本文为博主原创文章,未经博主允许不得转载。
BZOJ 1488 [HNOI2009]图的同构 Polya定理
原文:http://blog.csdn.net/wzq_qwq/article/details/48035455