题解 高中数列题
什么神仙题
拆式子,懒得再码一遍式子就直接粘题解了
大意是将原式写成 \(a_n=a+\sum\limits_{i=1}^nf(i)a_{p_i}\)
然后将后面的 \(a_{p_i}\) 展开和式变换后可以递归子问题
递归下去的多项式会递归 log 层,每层次数增加 \(m+1\)
所以这个复杂度是可以接受的,大概是 \(O(m^2 \log^3 n)\)?
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline ll read() {
ll ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
ll n, a, b, c, m;
int p[25];
const ll mod=1004535809;
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%mod,b>>=1) if (b&1) ans=ans*a%mod; return ans;}
namespace force{
int t[100000010];
inline ll f(ll i) {
ll ans=0;
for (int j=m; ~j; --j) ans=(ans*i+p[j])%mod;
return ans;
}
void solve() {
t[0]=a;
for (int i=1; i<=n; ++i) t[i]=(t[i-1]+f(i)*t[(i+b)/c])%mod;
printf("%d\n", t[n]);
}
}
namespace task{
inline ll p(ll n) {return (n+b)/c;}
inline ll q(ll n) {return n*c-b;}
struct poly{
int n;
ll a[15100], b[15100], c[15100], f[15100], x[15100], y[15100];
poly(){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
memset(f, 0, sizeof(f));
memset(x, 0, sizeof(x));
memset(y, 0, sizeof(y));
}
void lagrange() {
for (int i=1; i<=n; ++i) {
a[i]=1;
for (int j=1; j<=n; ++j) if (i!=j) a[i]=a[i]*(x[i]-x[j])%mod;
a[i]=y[i]*qpow(a[i], mod-2)%mod;
}
b[0]=1;
for (int i=1; i<=n; ++i) {
for (int j=i; j; --j) b[j]=(b[j-1]-x[i]*b[j])%mod;
b[0]=-x[i]*b[0]%mod;
}
for (int i=1; i<=n; ++i) {
ll inv=qpow(x[i], mod-2);
if (!inv) for (int j=0; j<n; ++j) c[j]=b[j+1];
else {
c[0]=-b[0]*inv%mod;
for (int j=1; j<n; ++j) c[j]=(c[j-1]-b[j])*inv%mod;
}
for (int j=0; j<n; ++j) f[j]=(f[j]+a[i]*c[j])%mod;
}
}
ll qval(ll x) {
ll ans=0; x%=mod;
for (int i=n-1; ~i; --i) ans=(ans*x+f[i])%mod;
return ans;
}
}f;
ll qsum(ll n, poly g) {
// cout<<"qsum: "<<n<<endl;
if (!n) return 0;
poly sg, h;
sg.n=g.n+1;
for (int i=1; i<=sg.n; ++i) sg.x[i]=i, sg.y[i]=g.qval(i);
for (int i=1; i<=sg.n; ++i) sg.y[i]=(sg.y[i-1]+sg.y[i])%mod;
sg.lagrange();
// cout<<n<<" f: "; for (int i=0; i<=sg.n; ++i) cout<<sg.f[i]<<' '; cout<<endl;
h.n=sg.n+m;
for (int i=1; i<=h.n; ++i) h.x[i]=i, h.y[i]=f.qval(i)*(sg.qval(n)-sg.qval(q(i)-1))%mod; //, cout<<f.qval(i)<<' '; cout<<endl;
h.lagrange();
return (a*sg.qval(n)+qsum(p(n), h))%mod;
}
void solve() {
f.n=m+1;
for (int i=0; i<=m; ++i) f.f[i]=read();
printf("%lld\n", ((a+qsum(n, f))%mod+mod)%mod);
}
}
signed main()
{
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout);
n=read(); a=read(); b=read(); c=read(); m=read();
// force::solve();
task::solve();
return 0;
}