BZOJ 3601 一个人的数论 ——莫比乌斯反演 高斯消元
http://www.cnblogs.com/jianglangcaijin/p/4033399.html
——lych_cys
我还是太菜了,考虑一个函数的值得时候,首先考虑是否积性函数,不行的话就强行展开,
如果是的话考虑最小因子的高次幂的情况
然后还要一点点猜想才行。
#include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define ll long long #define mp make_pair #define md 1000000007 ll d,m; ll h[110],a[110][110]; ll ksm(ll a,ll b) { if (b<0) return ksm(ksm(a,md-2),-b); ll ret=1; while (b) { if (b&1) (ret*=a)%=md; (a*=a)%=md; b>>=1; } return ret; } ll pp[110],A[110]; void init() { int i,j; for (i=0;i<=d+1;++i) { pp[i]=(ksm(i+1,d)+(i==0?0:pp[i-1]))%md; a[i][d+2]=pp[i]; a[i][0]=1; ll pre=1; for (j=1;j<=d+1;++j) { (pre*=(i+1))%=md; a[i][j]=pre; } } int k; for (i=0;i<=d+1;++i) { for (j=i;j<=d+1;++j) if (a[j][i]) break; if (i!=j) for (k=0;k<=d+2;++k) swap(a[i][k],a[j][k]); for (j=0;j<=d+1;++j) if (j!=i&&a[j][i]) { ll tmp=(a[j][i]*ksm(a[i][i],-1))%md; for (k=0;k<=d+2;++k) (a[j][k]-=tmp*a[i][k])%=md; } } for (i=0;i<=d+1;++i) A[i]=(a[i][d+2]*ksm(a[i][i],-1))%md; } ll dd[1220][3]; int main() { scanf("%lld%lld",&d,&m); init(); F(i,1,m) scanf("%lld%lld",&dd[i][0],&dd[i][1]); ll ans=0; F(i,0,d+1) { ll tmp=1; F(j,1,m) { tmp=tmp*ksm(dd[j][0],(ll)dd[j][1]*i)%md; tmp=tmp*(1-ksm(dd[j][0],d-i))%md; } ans+=A[i]*tmp%md; ans%=md; } ((ans%=md)+=md)%=md; printf("%lld\n",ans); }