题意
这个真的有、复杂。
思路
背包的思路很显然:
(F[i][j]=sum f(k)+F[i-1][j-k])
这个东西显然可以fft优化,但是复杂度还是过不了。
进一步观察式子
可以发现(F[i][j]=F[frac{i}{2}][k]*F[frac{i}{2}][j-k])
假设(F)的前缀和为(p),那么可以推出(p[i]=p[frac{i}{2}]+p[frac{i}{2}]*dp[frac{i}{2}])
那么像快速幂那样倍增优化即可。
代码
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T>inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write (T x) {
if (x<0) putchar('-'),x*=-1;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
template<typename T> struct poly {
T num[60000];
};
namespace Project {
const int N=60000;
const double pi=acos(-1);
typedef complex<double> cx;
typedef poly<int> py;
int n,m,p,A,o,s,u,L;
cx a[N],b[N];
int R[N];
py dp,g,org,tmp;
inline void add (py &x,py y) {
for (register int i=0; i<=m/2; ++i) x.num[i]=(x.num[i]+y.num[i])%p;
}
inline int f (int x) {
return (o*x*x%p+s*x%p+u)%p;
}
inline void fft (cx *tmp,int type) {
for (register int i=0; i<n; ++i) if (i<R[i]) swap(tmp[i],tmp[R[i]]);
for (register int i=1; i<n; i<<=1) {
cx wn(cos(pi/i),type*sin(pi/i));
for (register int j=0; j<n; j+=(i<<1)) {
cx w(1,0);
for (register int k=0; k<i; ++k,w*=wn) {
cx s=tmp[j+k],t=tmp[j+k+i]*w;
tmp[j+k]=s+t,tmp[j+k+i]=s-t;
}
}
}
}
inline void mul (py &res,py x,py y) {
for (register int i=0; i<n; ++i) {
a[i]=x.num[i],b[i]=y.num[i];
}
fft(a,1),fft(b,1);
for (register int i=0; i<n; ++i) a[i]*=b[i];
fft(a,-1);
for (register int i=0; i<=m/2; ++i) {
res.num[i]=static_cast<int>(a[i].real()/n+0.5)%p;
}
}
void ksm (int l) {
if (l==1) return dp=g=org,void();
ksm(l>>1);
mul(tmp,dp,g),add(dp,tmp),mul(g,g,g);
if (l&1) {
mul(g,org,g),add(dp,g);
}
}
inline void MAIN () {
read(n),read(p);
read(A),read(o),read(s),read(u);
m=2*n;
for (n=1; n<=m; n<<=1) ++L;
for (register int i=0; i<n; ++i) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
for (register int i=1; i<=m/2; ++i) org.num[i]=f(i);
ksm(A);
write(dp.num[m/2]);
}
}
int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
Project::MAIN();
}