Time:2016.08.18
Author:xiaoyimi
转载注明出处谢谢
传送门
思路:
真是太神了
我要能写出来一半,我就……
希望明年的自己能独立做出来
大犇博客
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define LL long long
#define mo 1000000007
using namespace std;
int d,w;
int p[1005],a[1005];
LL f[105][105],ans[105],h[105];
LL qr(LL x,LL y)
{
LL t=1;
for (x%=mo;y;y>>=1,x=x*x%mo)
if (y&1) t=t*x%mo;
return t;
}
void gauss(int n)
{
LL p;
for (int i=1;i<=n;++i)
{
int t=i;
for (int j=i+1;j<=n;++j)
if (f[t][i]<f[j][i]) t=j;
if (t!=i)
for (int j=i;j<=n+1;++j)
swap(f[t][j],f[i][j]);
for (int j=i+1;j<=n;++j)
{
p=f[j][i]*qr(f[i][i],mo-2)%mo;
for (int k=i+1;k<=n+1;++k)
f[j][k]=(f[j][k]-p*f[i][k]%mo)%mo;
}
}
for (int i=n;i;--i)
{
p=0;
for (int j=i+1;j<=n;++j) p=(p+ans[j]*f[i][j])%mo;
ans[i]=(f[i][n+1]-p)*qr(f[i][i],mo-2)%mo;
ans[i]=(ans[i]+mo)%mo;
}
}
main()
{
scanf("%d%d",&d,&w);
for (int i=1;i<=w;++i)
scanf("%d%d",p+i,a+i);
for (int i=1;i<=d+2;++i)
{
int t=1;
for (int j=1;j<=d+2;++j)
f[i][j]=t,
t=(LL)t*i%mo;
for (int j=1;j<=i;++j)
f[i][d+3]=(f[i][d+3]+qr(j,d))%mo;
}
gauss(d+2);
for (int i=0;i<=d+1;++i)
{
h[i]=ans[i+1];
for (int j=1;j<=w;++j)
{
h[i]=h[i]*qr(p[j],(LL)a[j]*i)%mo;
if (d-i>=0)
h[i]=h[i]*(1-qr(p[j],d-i))%mo;
else
h[i]=h[i]*(1-qr(qr(p[j],i-d),mo-2))%mo;
}
}
for (int i=1;i<=d+1;++i)
h[0]=(h[0]+h[i])%mo;
printf("%lld\n",(h[0]+mo)%mo);
}