题解 高中数列题

传送门

什么神仙题

拆式子,懒得再码一遍式子就直接粘题解了
image
image
image
大意是将原式写成 \(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;
}
posted @ 2022-01-21 20:14  Administrator-09  阅读(0)  评论(0编辑  收藏  举报