线性求逆元
1.这是求1~n
i的逆元为i^(-1) (mod p)
我令p=k*i+r,0<i<p,r<i
p=0(mod p)
k*i+r=0(mod p)
两边同时乘(i^(-1))*(r^(-1)),然后移项
i^(-1)=-k*r^(-1)(mod p)
i^(-1)=-(p/i)*(p%i)^(-1)(mod p)
故a[i]表示i的逆元
a[i]=-(p/i)*a[p%i](mod p)两边同时+p*(a[p%i])-->主要是为了保证是正数
a[i]+p*(a[p%i])=p-(p/i)*a[p%i](mod p)
又因为p*(a[p%i])=0(mod p)
a[i]=(p-p/i)*a[p%i](mod p)
2.求任意n个数的逆元
主要利用的性质是,积的逆元等于逆元的积
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 3000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) //by war //2019.8.7 using namespace std; long long n,p; long long s[N],inv[N],sv[N]; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } long long ksm(long long a,long long b){ long long r=1; while(b>0){ if(b&1) r=r*a%p; a=a*a%p; b>>=1; } return r; } signed main(){ in(n);in(p); s[0]=1; For(i,1,n) s[i]=s[i-1]*i%p; sv[n]=ksm(s[n],p-2); for(long long i=n;i;i--) sv[i-1]=sv[i]*i%p; For(i,1,n) o(s[i-1]*sv[i]%p),p(' '); return 0; }