[BZOJ3601] 一个人的数论 - 拉格朗日插值/伯努利数,狄利克雷卷积

非常容易发现,我们要求的函数F满足F卷上id_k(第i项为i^k)为一个多项式

然而这并没有什么用


#include"bits/stdc++.h"

using namespace std;

const int P=1000000007;
int power(int a,int t){
	int r=1;
	while(t){
		if(t&1)r=(long long)r*a%P;
		a=(long long)a*a%P;t>>=1;
	}
	return r;
}

const int N=1005,D=105;
int n,d,p[N],t[N],m,f[D],ans,g[D],h[D],tmp[D];

int F(int ti){
	int r=1;
	for(int i=1;i<=n;i++)r=(long long)r*(1-power(p[i],ti)+P)%P;
	return r;
}

int main(){
	scanf("%d%d",&d,&n);
	for(int i=m=1;i<=n;i++)scanf("%d%d",&p[i],&t[i]),m=(long long)m*power(p[i],t[i])%P;
	for(int i=1;i<=d+1;i++)g[i]=(g[i-1]+power(i,d))%P;
	for(int i=0,r;i<=d+1;i++){
		memset(h,0,sizeof(h));
		h[0]=1,r=g[i];
		for(int j=0;j<=d+1;j++)if(i!=j){
			memset(tmp,0,d+2<<2);
			for(int k=d+1;k>=1;k--)tmp[k]=((h[k-1]-(long long)j*h[k])%P+P)%P;
			tmp[0]=(P-(long long)j*h[0]%P)%P;
			memcpy(h,tmp,d+2<<2);
			r=(long long)r*power((i-j+P)%P,P-2)%P;
		}
		for(int j=0;j<=d+1;j++)f[j]=(f[j]+(long long)r*h[j])%P;
	}
	for(int i=1,s=m;i<=d+1;i++){
		ans=(ans+(long long)s*f[i]%P*F((d-i+P-1)%(P-1)))%P;
		s=(long long)s*m%P;
	}
	printf("%d\n",ans);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值