• Luogu5349 幂


    题面

    题解

    首先考虑对于一个单项式怎么做,多项式就是单项式的答案的和。

    就求一下(mathbf f(n) = n^k)吧。(下面设(t = dfrac 1r)

    (mathbf S_k = sum_{n=0}^infty n^k left(dfrac 1t ight)^n)

    (tmathbf S_k = sum_{n=1}^infty n^k left(dfrac 1t ight)^{n-1} = sum_{n=0}^infty (n+1)^k left(dfrac 1t ight)^n)

    所以((t - 1) mathbf S_k = sum_{n=0}^infty [(n+1)^k - n^k]left(dfrac 1t ight)^n)

    ((n+1)^k)用二项式定理展开可以发现:

    (mathbf S_k = dfrac 1{t-1} sum_{i=0}^{k-1} inom ki mathbf S(i), mathbf S_0 = dfrac t{t-1})

    于是(mathbf S_{k} = dfrac {k!}{t-1}sum_{i=0}^{k-1} dfrac 1{(k - i)!} dfrac {mathbf S(i)}{i!})

    显然卷积的形式,分治(mathrm{FFT})即可。

    代码

    我不会告诉你我是直接蒯的分治FFT的代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    #define clear(x, y) memset(x, y, sizeof(x))
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int Mod(998244353), G(3), maxn(3e5 + 10), phi(Mod - 1);
    inline int fastpow(int x, int y)
    {
    	int ans = 1;
    	while(y)
    	{
    		if(y & 1) ans = 1ll * ans * x % Mod;
    		x = 1ll * x * x % Mod, y >>= 1;
    	}
    	return ans;
    }
    
    inline int Inv(int x) { return fastpow(x, Mod - 2); }
    int r[maxn], N, m, f[maxn], g[maxn], fac[maxn], inv[maxn], invk;
    template<int opt> void FFT(int *p)
    {
    	for(RG int i = 0; i < N; i++) if(i < r[i]) std::swap(p[i], p[r[i]]);
    	for(RG int i = 1; i < N; i <<= 1)
    	{
    		int rot = fastpow(G, phi / (i << 1));
    		for(RG int j = 0; j < N; j += (i << 1))
    		{
    			int w = 1;
    			for(RG int k = 0; k < i; ++k, w = 1ll * w * rot % Mod)
    			{
    				int x = p[j + k], y = 1ll * w * p[i + j + k] % Mod;
    				p[j + k] = (x + y) % Mod, p[i + j + k] = (x - y + Mod) % Mod;
    			}
    		}
    	}
    	if(opt == -1) std::reverse(p + 1, p + N);
    }
    
    void Div(int l, int r)
    {
    	static int a[maxn], b[maxn], P;
    	if(r - l <= 1) return;
    	int mid = (l + r) >> 1;
    	Div(l, mid);
    	for(m = r - l, N = 1, P = -1; N <= m; N <<= 1, ++P);
    	int invn = Inv(N);
    	for(RG int i = 0; i < N; i++)
    		::r[i] = (::r[i >> 1] >> 1) | ((i & 1) << P);
    	std::copy(f + l, f + mid, a); std::fill(a + mid - l, a + N, 0);
    	for(RG int i = 0; i < mid - l; i++) a[i] = 1ll * a[i] * inv[i + l] % Mod;
    	std::copy(inv, inv + r - l, b); std::fill(b + r - l, b + N, 0);
    	FFT<1>(a), FFT<1>(b);
    	for(RG int i = 0; i < N; i++) a[i] = 1ll * a[i] * b[i] % Mod;
    	FFT<-1>(a);
    	for(RG int i = mid; i < r; i++)
    		f[i] = (f[i] + 1ll * fac[i] * a[i - l] % Mod * invk % Mod * invn % Mod) % Mod;
    	Div(mid, r);
    }
    
    int n, k;
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	n = read() + 1, k = Inv(read()); invk = Inv(k - 1); fac[0] = inv[0] = 1;
    	for(RG int i = 1; i <= n + n; i++) fac[i] = 1ll * fac[i - 1] * i % Mod;
    	inv[n + n] = Inv(fac[n + n]);
    	for(RG int i = n + n - 1; i; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % Mod;
    	f[0] = 1ll * k * invk % Mod; Div(0, n);
    	int ans = 0;
    	for(RG int i = 0; i < n; i++)
    		ans = (ans + 1ll * read() * f[i] % Mod) % Mod;
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    timestamp与timedelta,管理信息系统概念与基础
    datetime处理日期和时间
    中文词频统计
    文件方式实现完整的英文词频统计实例
    组合数据类型练习,英文词频统计实例上
    英文词频统计预备,组合数据类型练习
    加载静态文件,父模板的继承和扩展
    开始Flask项目
    夜间模式的开启与关闭,父模板的制作
    完成登录与注册页面的前端
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10812424.html
Copyright © 2020-2023  润新知