【模板】拉格朗日插值
点击查看代码
#include
using namespace std;
int n,k;
long long x[2005],y[2005];
const long long md=998244353;
inline long long pwr(long long x,long long y){
long long res=1;
while(y){
if(y&1)res=res*x%md;
x=x*x%md;y>>=1;
}return res;
}
inline long long Lagrange(int t){
long long res=0;
for(int i=1;i<=n;i++){
long long tmp=y[i];
for(int j=1;j<=n;j++){
if(i!=j)tmp=tmp*(x[j]-t)%md*pwr(x[j]-x[i],md-2)%md;
}res=(res+tmp)%md;
}return (res+md)%md;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%lld%lld",&x[i],&y[i]);
printf("%lld",Lagrange(k));
return 0;
}
拉格朗日插值2
点击查看代码
#include
using namespace std;
int n,m;
const int md=998244353,G=3,Gi=(md+1)/3;
int r[1<<20],lim;
inline int pwr(int x,int y){
int res=1;
while(y){
if(y&1)res=1ll*res*x%md;
x=1ll*x*x%md;y>>=1;
}
return res;
}
inline void NTT(int *dp,int W){
for(int i=0;i<(1<>1]>>1)+((i&1)<<(lim-1));
fac[0]=fac[1]=inv[0]=inv[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=n;i++)fac[i]=1ll*fac[i-1]*i%md;
for(int i=2;i<=n;i++)inv[i]=1ll*(md-md/i)*inv[md%i]%md;
for(int i=2;i<=n;i++)ifac[i]=1ll*inv[i]*ifac[i-1]%md;
}
int f[1<<20],g[1<<20],ltmp[400005],rtmp[400005];
int main(){
scanf("%d%d",&n,&m);init();
for(int i=0;i<=n;i++)scanf("%d",&f[i]);
for(int i=0;i<=n;i++)f[i]=1ll*f[i]*ifac[i]%md*ifac[n-i]%md;
for(int i=0;i<=n;i++)if((n-i)&1)f[i]=(md-f[i])%md;
for(int i=0;i<=2*n;i++)g[i]=pwr(m-n+i,md-2);
NTT(f,G);NTT(g,G);int INV=pwr((1<
[集训队互测 2012] calc
点击查看代码
#include
using namespace std;
int k,n,md;
int fac[1005],inv[1005],ifac[1005];
inline void init(){
fac[0]=fac[1]=inv[0]=inv[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=2*n+1;i++)fac[i]=1ll*fac[i-1]*i%md;
for(int i=2;i<=2*n+1;i++)inv[i]=1ll*(md-md/i)*inv[md%i]%md;
for(int i=2;i<=2*n+1;i++)ifac[i]=1ll*ifac[i-1]*inv[i]%md;
}
int pre[1005],suf[1005];
inline int lag(int *f,int len,int x){
int res=0;pre[0]=x%md;suf[len+1]=1;
for(int i=1;i<=len;i++)pre[i]=1ll*pre[i-1]*(x-i)%md;
for(int i=len;i>=0;i--)suf[i]=1ll*suf[i+1]*(x-i)%md;
for(int i=0;i<=len;i++){
int tmp=1ll*f[i]*ifac[i]%md*ifac[len-i]%md*((len-i)&1?md-1:1)%md;
if(i)tmp=1ll*tmp*pre[i-1]%md;
if(i!=len)tmp=1ll*tmp*suf[i+1]%md;
res=(res+tmp)%md;
}
return res;
}
int dp[505][1005];
int main(){
scanf("%d%d%d",&k,&n,&md);
init();
dp[0][0]=1;
for(int i=1;i<=n;i++){
int sum=dp[i-1][0];
for(int j=1;j<=2*n+1;j++){
dp[i][j]=1ll*j*sum%md;
sum=(sum+dp[i-1][j])%md;
}
}
for(int i=1;i<=2*n+1;i++)dp[n][i]=(dp[n][i]+dp[n][i-1])%md;
dp[n][0]=lag(dp[n],2*n+1,k);
printf("%lld",(1ll*dp[n][0]*fac[n]%md+md)%md);
return 0;
}
[TJOI2018]教科书般的亵渎
点击查看代码
#include
using namespace std;
const int md=1e9+7;
int T;
long long n;
int m;
int a[55],k,f[55],pre[55],suf[55],fac[55];
map ma;
inline int pwr(int x,int y){
int res=1;
while(y){
if(y&1)res=1ll*res*x%md;
x=1ll*x*x%md;y>>=1;
}
return res;
}
inline int lag(long long x){
if(x<=k+2)return f[x];
int res=0;pre[0]=1;suf[k+3]=1;x%=md;
for(int i=1;i<=k+2;i++)pre[i]=1ll*pre[i-1]*(x-i)%md;
for(int i=k+2;i>=1;i--)suf[i]=1ll*suf[i+1]*(x-i)%md;
for(int i=1;i<=k+2;i++){
int x=1ll*pre[i-1]*suf[i+1]%md;
int fu=((k+2-i)&1)?-1:1;
int y=1ll*fac[i-1]*fac[k+2-i]%md*fu%md;
res=(res+1ll*f[i]*x%md*pwr(y,md-2)%md)%md;
}
return (res+md)%md;
}
inline void init(){
fac[0]=1;
for(int i=1;i<=52;i++)fac[i]=1ll*fac[i-1]*i%md;
}
int main(){
scanf("%d",&T);init();
while(T--){
scanf("%lld%d",&n,&m);k=m+1;
ma.clear();
for(int i=1;i<=m;i++)scanf("%d",&a[i]),ma[a[i]]=1;
sort(a+1,a+m+1);
while(ma[n])n--,k--,m--;
for(int i=1;i<=k+2;i++)f[i]=(f[i-1]+pwr(i,k))%md;
int res=lag(n);
for(int i=1;i<=m;i++)res=(res-pwr(a[i],k))%md;
for(int i=1;i<=m;i++)res=(res+lag(n-a[i]))%md;
for(int i=1;i<=m;i++){
for(int j=i-1;j>=1;j--){
res=(res-pwr(a[i]-a[j],k))%md;
}
}
printf("%d\n",(res+md)%md);
}
return 0;
}
[NOI2019] 机器人
点击查看代码
#include
using namespace std;
int n;
const int md=1e9+7;
namespace Lagrange{
int pre1[305],suf1[305],pre2[305],suf2[305],inv[305];
inline void init(){
inv[0]=inv[1]=1;
for(int i=2;i<=n;i++)inv[i]=1ll*(md-md/i)*inv[md%i]%md;
}
inline int lag(int *y,int k,int t){
if(t<=k)return y[t];
pre1[0]=suf1[0]=suf2[k+1]=1;pre2[0]=t%md;
for(int i=1;i<=k;i++)pre1[i]=1ll*pre1[i-1]*inv[i]%md;
for(int i=1;i<=k;i++)suf1[i]=1ll*suf1[i-1]*-inv[i]%md;
for(int i=1;i<=k;i++)pre2[i]=1ll*pre2[i-1]*(t-i)%md;
for(int i=k;i>=1;i--)suf2[i]=1ll*suf2[i+1]*(t-i)%md;
int res=0;
for(int i=0;i<=k;i++)res=(res+1ll*y[i]*pre1[i]%md*suf1[k-i]%md*(i?pre2[i-1]:1)%md*suf2[i+1])%md;
return (res+md)%md;
}
}
using Lagrange::lag;
int A[305],B[305],lim;
int vis[305][305],cnt,L[3005],R[3005],dp[3005][10005];
void build(int l,int r){
if(l>r||vis[l][r])return ;
vis[l][r]=++cnt;L[cnt]=l;R[cnt]=r;
if(l==r)return ;
for(int i=l;i<=r;i++){
if(abs((r-i)-(i-l))>2)continue;
build(l,i-1);build(i+1,r);
}
}
bool used[305][305];
void solve(int l,int r,int len,int v){
if(l>r||used[l][r])return ;
int id=vis[l][r];used[l][r]=1;
for(int i=1;i<=len;i++)dp[id][i]=0;
for(int i=l;i<=r;i++){
if(abs((r-i)-(i-l))>2||A[i]>v||B[i]<=v)continue;
solve(l,i-1,len,v);solve(i+1,r,len,v);
for(int j=1;j<=len;j++)dp[id][j]=(dp[id][j]+1ll*dp[vis[l][i-1]][j]*dp[vis[i+1][r]][j-1])%md;
}
for(int i=1;i<=len;i++)dp[id][i]=(dp[id][i]+dp[id][i-1])%md;
}
inline void Getval(int l,int r){
for(int i=1;i<=cnt;i++)dp[i][0]=lag(dp[i],R[i]-L[i]+1,r-l+1);
for(int l=1;l<=n;l++)for(int r=l;r<=n;r++)used[l][r]=0;
}
vector hsh;
int main(){
scanf("%d",&n);
Lagrange::init();
for(int i=1;i<=n;i++)scanf("%d%d",&A[i],&B[i]),++B[i];
for(int i=1;i<=n;i++)hsh.push_back(A[i]);
for(int i=1;i<=n;i++)hsh.push_back(B[i]);
sort(hsh.begin(),hsh.end());
hsh.erase(unique(hsh.begin(),hsh.end()),hsh.end());
for(int i=1;i<=n;i++)A[i]=upper_bound(hsh.begin(),hsh.end(),A[i])-hsh.begin();
for(int i=1;i<=n;i++)B[i]=upper_bound(hsh.begin(),hsh.end(),B[i])-hsh.begin();
for(int i=0;i<=n;i++)dp[0][i]=1;
build(1,n);
for(int i=0;i+1
[APIO2016]划艇
点击查看代码
#include
using namespace std;
int n;
int a[505],b[505];
vector hsh;
const int md=1e9+7;
int fac[505],inv[505],ifac[505];
inline void init(){
fac[0]=fac[1]=inv[0]=inv[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=n;i++)fac[i]=1ll*fac[i-1]*i%md;
for(int i=2;i<=n;i++)inv[i]=1ll*(md-md/i)*inv[md%i]%md;
for(int i=2;i<=n;i++)ifac[i]=1ll*ifac[i-1]*inv[i]%md;
}
int tmp[505],pre[505],suf[505];
inline int lag(int *f,int len,int x){
if(x<=len)return f[x];
int res=0;pre[0]=x%md;suf[len+1]=1;
for(int i=1;i<=len;i++)pre[i]=1ll*pre[i-1]*(x-i)%md;
for(int i=len;i>=0;i--)suf[i]=1ll*suf[i+1]*(x-i)%md;
for(int i=0;i<=len;i++){
int tmp=1ll*f[i]*ifac[i]%md*ifac[len-i]%md*((len-i)&1?md-1:1)%md;
if(i)tmp=1ll*tmp*pre[i-1]%md;
if(i!=len)tmp=1ll*tmp*suf[i+1]%md;
res=(res+tmp)%md;
}
return res;
}
int dp[505][505];
int main(){
scanf("%d",&n);init();
for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]),b[i]++;
for(int i=1;i<=n;i++)hsh.push_back(a[i]);
for(int i=1;i<=n;i++)hsh.push_back(b[i]);
sort(hsh.begin(),hsh.end());
hsh.erase(unique(hsh.begin(),hsh.end()),hsh.end());
for(int i=1;i<=n;i++)a[i]=upper_bound(hsh.begin(),hsh.end(),a[i])-hsh.begin();
for(int i=1;i<=n;i++)b[i]=upper_bound(hsh.begin(),hsh.end(),b[i])-hsh.begin();
for(int i=0;i<=n;i++)dp[i][0]=1;
for(int t=1;tt){
int sum=dp[i-1][0];
for(int j=1;j<=n;j++){
dp[i][j]=(sum+dp[i-1][j])%md;
sum=(sum+dp[i-1][j])%md;
}
}
else for(int j=1;j<=n;j++)dp[i][j]=dp[i-1][j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++)dp[i][j]=(dp[i][j]+dp[i][j-1])%md;
dp[i][0]=lag(dp[i],i,hsh[t]-hsh[t-1]);
}
}
printf("%d",(dp[n][0]+md-1)%md);
return 0;
}