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\n",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 */