[Lagrange polynomial] [dp] Luogu P4463 calc

 

Title Description

A sequence A_1, \ cdots, A_N A . 1 , , A n- is valid, if and only if:

A length of a given n- n-.

A_1, \ cdots, A_N A . 1 , , A n- is [. 1, A] [ . 1 , A ] is an integer.

A_1, \ cdots, A_N A . 1 , , A n- equal to each other.

Value is defined as a sequence number of all the product inside it, i.e. A_1 \ Times A_2 \ Times \ cdots \ Times A_N A . 1 × A 2 × × A n- .

Find all the values ​​of the different sequences and legitimate.

Two different sequences if and only if they are not the same as any one.

The answer to a number of output MOD m O take over the results. D.

 

answer

  • We can first count out an incremental contribution and for the contribution and * n!
  • Set F [i] [j] denotes the front i values ​​are less than the number selected is equal to the contribution of j and proceeds to f [i] [j] = f [i-1] [j -] * j + f [i ] [j-1]
  • And then we can do violence like Lagrange polynomial

 

Code

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define ll long long 
 5 int a,n,mo,res,m,f[510][1010],y[1010];
 6 using namespace std;
 7 int ksm(int a,int b) { int r=1; for (;b;b>>=1,a=1ll*a*a%mo) if (b&1) r=1ll*r*a%mo; return r; }
 8 int change(int x)
 9 {
10     if (x>=1&&x<=m) return y[x];
11     int r=0;
12     for (int i=1;i<=m;i++)
13     {
14         int p=y[i],q=1;
15         for (int j=1;j<=m;j++) if (i!=j) p=1ll*p*(x-j)%mo,q=1ll*q*(i-j)%mo;
16         p<0?p+=mo:0,q<0?q+=mo:0,r=(r+1ll*p*ksm(q,mo-2))%mo;
17     }
18     return r;
19 }
20 int main()
21 {
22     scanf("%d%d%d",&a,&n,&mo),res=1,m=2*n+1;
23     for (int i=1;i<=n;i++) res=1ll*res*i%mo;
24     for (int i=0;i<=m;i++) f[0][i]=1;
25     for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) f[i][j]=(1ll*f[i-1][j-1]*j+f[i][j-1])%mo;
26     for (int i=1;i<=m;i++) y[i]=f[n][i];
27     printf("%lld",1ll*res*change(a)%mo);     
28 }

 

Guess you like

Origin www.cnblogs.com/Comfortable/p/11269333.html