zoukankan      html  css  js  c++  java
  • [洛谷P4721]【模板】分治 FFT

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求:

    $$
    f_i=sum_{j=1}^if_{i-j}g_j\
    f_0=1
    $$

    题解:直接求复杂度是$O(n^2)$,明显不可以通过此题

    分治$FFT$,可以用$CDQ$分治,先求出$f_{[l,mid)}$,可以发现这部分对区间的$f_{[mid,r)}$的贡献是$f_{[l,mid)}*g_{[0,r-l)}$,卷出来加到对应位置就行了,复杂度$O(nlog_2^2n)​$

    卡点:

    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    namespace std {
    	struct istream {
    #define M (1 << 21 | 3)
    		char buf[M], *ch = buf - 1;
    		inline istream() {
    #ifndef ONLINE_JUDGE
    			freopen("input.txt", "r", stdin);
    #endif
    			fread(buf, 1, M, stdin);
    		}
    		inline istream& operator >> (int &x) {
    			while (isspace(*++ch));
    			for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
    			return *this;
    		}
    #undef M
    	} cin;
    	struct ostream {
    #define M (1 << 21 | 3)
    		char buf[M], *ch = buf - 1;
    		int w;
    		inline ostream& operator << (int x) {
    			if (!x) {
    				*++ch = '0';
    				return *this;
    			}
    			for (w = 1; w <= x; w *= 10);
    			for (w /= 10; w; w /= 10) *++ch = (x / w) ^ 48, x %= w;
    			return *this;
    		}
    		inline ostream& operator << (const char x) {*++ch = x; return *this;}
    		inline ~ostream() {
    #ifndef ONLINE_JUDGE
    			freopen("output.txt", "w", stdout);
    #endif
    			fwrite(buf, 1, ch - buf + 1, stdout);
    		}
    #undef M
    	} cout;
    }
    
    #define maxn 131072 | 3
    const int mod = 998244353, G = 3;
    
    namespace Math {
    	inline int pw(int base, int p) {
    		static int res;
    		for (res = 1; p; p >>= 1, base = static_cast<long long> (base) * base % mod) if (p & 1) res = static_cast<long long> (res) * base % mod;
    		return res;
    	}
    	inline int inv(int x) {return pw(x, mod - 2);}
    }
    
    int n;
    int f[maxn], g[maxn];
    namespace Poly {
    #define N 131072 | 3
    	int s, lim, ilim, rev[N];
    	int Wn[N + 1];
    	inline void reduce(int &x) {x += x >> 31 & mod;}
    	inline void clear(register int *l, const int *r) {
    		if (l >= r) return ;
    		while (l != r) *l++ = 0;
    	}
    	inline void init(const int n) {
    		s = -1, lim = 1; while (lim <= n) lim <<= 1, s++; ilim = Math::inv(lim);
    		for (int i = 1; i < lim; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
    		const int t = Math::pw(G, (mod - 1) / lim);
    		*Wn = 1; for (register int *i = Wn; i != Wn + lim; ++i) *(i + 1) = static_cast<long long> (*i) * t % mod;
    	}
    
    	inline void NTT(int *A, const int op = 1) {
    		for (register int i = 1; i < lim; i++) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
    		for (register int mid = 1; mid < lim; mid <<= 1) {
    			const int t = lim / mid >> 1;
    			for (register int i = 0; i < lim; i += mid << 1) {
    				for (register int j = 0; j < mid; j++) {
    					const int W = op ? Wn[t * j] : Wn[lim - t * j];
    					const int X = A[i + j], Y = static_cast<long long> (A[i + j + mid]) * W % mod;
    					reduce(A[i + j] += Y - mod), reduce(A[i + j + mid] = X - Y);
    				}
    			}
    		}
    		if (!op) for (int i = 0; i < lim; i++) A[i] = static_cast<long long> (A[i]) * ilim % mod;
    	}
    
    	int A[N], B[N];
    	void CDQ_NTT(const int l, const int r) {
    		if (r - l < 2) return ;
    		const int mid = l + r >> 1;
    		CDQ_NTT(l, mid); init(r - l);
    		std::copy(f + l, f + mid, A); clear(A + mid - l, A + lim);
    		std::copy(g, g + r - l, B); clear(B + r - l, B + lim);
    		NTT(A), NTT(B);
    		for (int i = 0; i < lim; i++) A[i] = static_cast<long long> (A[i]) * B[i] % mod;
    		NTT(A, 0);
    		for (int i = mid; i < r; i++) reduce(f[i] += A[i - l] - mod);
    		CDQ_NTT(mid, r);
    	}
    #undef N
    }
    
    int main() {
    	std::cin >> n;
    	for (int i = 1; i < n; i++) std::cin >> g[i];
    	*f = 1;
    	Poly::CDQ_NTT(0, n);
    	for (int i = 0; i < n; i++) std::cout << f[i] << ' ';
    	std::cout << '
    ';
    	return 0;
    }
    

      

  • 相关阅读:
    python运维之saltstack方式
    windows下使用vim
    django-redis中文文档
    Skipping GMP tests ([WinError 126] 找找不不到到指指定定的的模模块块。。)
    python pycryptodome库,及后台支付宝功能接入
    关于python时间相关的函数记录集合
    mysql练习题博客集
    mysql -uroot -p -P3306 -h192.168.0.111无法远程连接mysql
    报错 Storing debug log for failure in /root/.pip/pip.log
    多进程 库multiprocessing
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10127918.html
Copyright © 2011-2022 走看看