BZOJ3601 一個人的數論【莫比烏斯反演+拉格朗日插值求自然數冪和多項式係數】

題目描述:

在這裏插入圖片描述

題目分析:

這似乎是官方題解:題解1
這是比較詳細的題解:題解2

拉格朗日插值求係數調錯調了1h+…

#include<bits/stdc++.h>
#define maxn 105
using namespace std;
const int mod = 1e9+7;
int d,n,a[maxn],s[maxn],f[maxn],len;
inline int Pow(int a,int b){
	int s=1;
	for(;b;b>>=1,a=1ll*a*a%mod) b&1&&(s=1ll*s*a%mod);
	return s;
}
inline void Mul(int *f,int t){//f*(x-t)
	for(int i=++len;i>0;i--) f[i]=((i?f[i-1]:0)-1ll*t*f[i])%mod;
}
inline void Div(int *f,int t){//f/(x-t)
	int pre=0,now;
	for(int i=len--;i>=0;i--,pre=now) now=f[i],f[i]=(pre+1ll*f[i+1]*t)%mod;
}
void Lagrange_Polynomial(){
	f[0]=1; int D=1,Y=0;
	for(int i=0;i<=d+1;i++) Mul(f,i);
	for(int i=1;i<=d+1;i++) D=1ll*D*(0-i)%mod; D=Pow(D,mod-2);
	for(int i=0;i<=d+1;i++){
		Div(f,i),Y=(Y+Pow(i,d))%mod;
		for(int j=0;j<=d+1;j++) a[j]=(a[j]+1ll*Y*D%mod*f[j])%mod;
		Mul(f,i),D=1ll*D*(i-(d+1))%mod*Pow(i+1,mod-2)%mod;
	}
}
int main()
{
	scanf("%d%d",&d,&n);
	Lagrange_Polynomial();
	for(int i=1;i<=d+1;i++) s[i]=1;
	for(int o=1,p,k;o<=n;o++){
		scanf("%d%d",&p,&k);
		for(int i=0;i<=d+1;i++)
			s[i]=1ll*s[i]*(Pow(p,1ll*k*i%(mod-1))-Pow(p,(1ll*k*i+d-i)%(mod-1)))%mod;
	}
	int ans=0;
	for(int i=0;i<=d+1;i++) ans=(ans+1ll*a[i]*s[i])%mod;
	printf("%d\n",(ans+mod)%mod);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章