这是你从未见过的全新版本,常数优秀(相信我),简单好用,背一下用一年
以后还会更新exp,ln之类的
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define rep(a,b,c) for (int a=b;a<=c;a++)
#define per(a,b,c) for (int a=b;a>=c;a--)
#define go(u) for (int o=ft[u],v;v=E[o].t;o=E[o].n)
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef double dob;
typedef pair<int,int> par;
const int N=300010,P=1005060097,g=5,ig=(P*2+1)/5;
LL pw(LL x,LL k){
LL y=1;
while (k){
if (k&1) y=y*x%P;
x=x*x%P;
k>>=1;
}
return y;
}
namespace po{
LL a[N],b[N],c[N];
void dft(LL* a,int n,int op){
static LL r[N];
r[0]=0;
for (int i=0;i<n;i+=2){
r[i]=r[i>>1]>>1;
r[i+1]=r[i]|n>>1;
}
for (int i=0;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int h=2;h<=n;h<<=1){
LL wn=pw(op==1?g:ig,(P-1)/h);
for (int i=0;i<n;i+=h){
LL w=1;
for (int j=i;j<i+h/2;j++){
LL x=a[j],y=a[j+h/2];
a[j]=(x+y*w)%P;
a[j+h/2]=(x-y*w)%P;
w=w*wn%P;
}
}
}
if (op==-1) for (int i=0,iv=pw(n,P-2);i<n;i++) a[i]=a[i]*iv%P;
}
void mul(LL* _a,LL* _b,LL* _c,int len){
memcpy(a,_a,len*8);
memcpy(b,_b,len*8);
dft(a,len,1),dft(b,len,1);
rep(i,0,len-1) c[i]=a[i]*b[i]%P;
dft(c,len,-1);
memcpy(_c,c,len*8);
}
void inv(LL* _b,LL* _a,int len){
int nw=2;
_b[0]=pw(_a[0],P-2);
while (nw<=len){
memcpy(b,_b,nw*8);
memset(b+nw,0,nw*8);
memcpy(a,_a,nw*8);
memset(a+nw,0,nw*8);
po::dft(b,nw*2,1);
po::dft(a,nw*2,1);
for (int i=0;i<nw*2;i++) b[i]=b[i]*(2-a[i]*b[i]%P)%P;
po::dft(b,nw*2,-1);
for (int i=0;i<nw;i++) _b[i]=b[i];
nw<<=1;
}
}
};
struct poly{
int l;
vector <LL> a;
LL& operator [](int k){return a[k];}
void set(int len){
while (a.size()<len) a.push_back(0);
while (l>len) a[--l]=0;
l=len;
}
void operator *=(poly k){
int len=1;
while (len<l+k.l-1) len<<=1;
set(len),k.set(len);
po::mul(&a[0],&k[0],&a[0],len);
}
void operator /=(poly k){
if (k[0]==0){puts("no inv");return;}
int len=1;
while (len<k.l) len<<=1;
set(0),set(len),k.set(len);
po::inv(&a[0],&k[0],len);
}
}p1,p2;
int n,m,a[N];
int main(){
scanf("%d%d",&n,&m);
rep(i,1,m) scanf("%d",a+i);
p2.set(n+1);
rep(i,1,m) if (a[i]<=n) --p2[a[i]];
++p2[0];// p2 = 1-f(x)
p1/=p2;
printf("%lld\n",(p1[n]+P)%P);
return 0;
}
=====================================
#include<iostream>
using namespace std;
#define F f[tp]
#define G f[tp^1]
#define X x*m+y
#define Y x*m*2+y
#define MXN 1048576
#define md 1004535809
typedef long long ll;
ll N,tp,i,j,inv,A[MXN],B[MXN],f[2][MXN],w[MXN];
string s;
int n,m,x,y;
void DFT(){
for (tp=0,n=N,m=1;m<N;n>>=1,m<<=1,tp^=1)
for (x=0;x*2<n;x++) for (y=0;y<m;y++)
G[Y]=(F[X]+F[X+N/2]*w[y*n/2])%md,
G[Y+m]=(F[X]-F[X+N/2]*w[y*n/2])%md;
}
ll pw(ll x,ll k){
ll t=1;
for (;k;k>>=1,x=x*x%md)
if (k&1) t=t*x%md;
return t;
}
int main(){
N=1048576;
cin>>s;
for (i=tp=0,j=s.size();i<N&&j!=0;) F[i++]=s[--j]-'0';
for (;i<N;) F[i++]=0;
for (w[0]=1,w[1]=pw(3,(md-1)/N),i=2;i<N;i++)
w[i]=w[i-1]*w[1]%md;
DFT();
for (i=0;i<N;i++) A[i]=F[i];
cin>>s;
for (i=tp=0,j=s.size();i<N&&j!=0;) F[i++]=s[--j]-'0';
for (;i<N;) F[i++]=0;
DFT();
for (i=0;i<N;i++) B[i]=F[i];
for (i=tp=0;i<N;i++) F[i]=A[i]*B[i]%md;
for (w[0]=1,w[1]=w[N-1],i=2;i<N;i++)
w[i]=w[i-1]*w[1]%md;
DFT();
inv=pw(N,md-2);
for (i=N-1;i>-1;i--) F[i]=(F[i]*inv%md+md)%md;
for (i=j=0;i<N;i++) F[i]+=j,j=F[i]/10,F[i]=F[i]%10;
while (F[N-1]==0) N--;
for (i=N-1;i>-1;i--) cout<<F[i];
return 0;
}
UPD:修改了一些,更好背一点
void DFT(LL *a,int n,LL w0){
LL i,j,k=0;
for (i=w[0]=1;i<n;i++) w[i]=w[i-1]*w0%P;
for (i=0;i<n;i++) f[i]=a[i];
for (;i;k++,swap(f,g)) for (i=0;i<n>>k+1;i++) for (j=0;j<1<<k;j++)
g[i<<k+1|j] =(f[i<<k|j]+f[i<<k|j|n>>1]*w[j*n>>k+1])%P,
g[i<<k+1|j|1<<k]=(f[i<<k|j]-f[i<<k|j|n>>1]*w[j*n>>k+1])%P;
for (i=0;i<n;i++) a[i]=g[i];
}
UPD:常数更小的写法, 强大学弟的blog