bzoj 1488

基本同bzoj 1815,一个图的边用或者不用可以看做黑白染色,这样就是bzoj 1815在m=2,p=997时的特例了

bzoj 1815没做过看这里

(这两道题有一点要注意:在计算时里面有一个部分是指数,千万不要一不小心在算指数的时候也取了模!!!)

贴代码:

#include <cstdio>
#define ll unsigned long long
using namespace std;
ll n,m=2,p=997;
ll mul[70];
ll num[70];
ll GCD[70][70];
ll ret=0;
ll pow_mul(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1)ans=ans*x%p;
        x=x*x%p,y>>=1;
    }
    return ans;
}
ll gcd(ll x,ll y)
{
    return y?gcd(y,x%y):x;
}
void init()
{
    mul[0]=mul[1]=1;
    for(ll i=2;i<=n;i++)mul[i]=mul[i-1]*i%p;
    for(ll i=1;i<=n;i++)for(ll j=i;j<=n;j++)GCD[i][j]=GCD[j][i]=gcd(i,j);
}
ll get_ans(int ttop)
{
    ll sum=0,fm=1,cnt=0;
    for(int i=1;i<=ttop;i++)
    {
        sum=sum+(num[i]>>1),fm=(fm*num[i]%p);
        if(num[i]!=num[i-1])fm=fm*mul[cnt]%p,cnt=1;
        else cnt++;
        for(int j=i+1;j<=ttop;j++)sum=sum+GCD[num[i]][num[j]];
    }
    fm=fm*mul[cnt]%p;
    ll S=pow_mul(fm,p-2);
    return S*pow_mul(m,sum)%p;
}
void dfs(int dep,ll ed,ll las)
{
    if(!ed)ret=(ret+get_ans(dep-1))%p;
    else
    {
        for(ll i=las;i<=ed>>1;i++)
        {
            num[dep]=i;
            dfs(dep+1,ed-i,i);
            num[dep]=0;
        }
        num[dep]=ed;
        dfs(dep+1,0,ed);
        num[dep]=0;
    }
}
int main()
{
    scanf("%llu",&n);
    init();
    dfs(1,n,1);
    printf("%llu
",ret);
    return 0;
}
/*
0,1,2,4,11,34,156,47,382,493,291,56,400,993,778,96,890,888,766,749,7,304,785,887,46,799,403,68,742,852,567,582,803,231,122,61,761,151,931,617,870,170,736,521,412,976,217,383,119,447,314,793,952,321,665,663,780,791,78,403,683
*/
原文地址:https://www.cnblogs.com/zhangleo/p/10968926.html