luogu P3803 NTT模板

NTT模板题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<fstream>

using namespace std;
typedef long long ll;
const int N = 3e6 + 105;
const int mod = 998244353;
const double Pi = acos(- 1.0);
const int INF = 0x3f3f3f3f;
//NTT所需
const int G = 3, Gi = 332748118;

inline int read() {
	char ch = getchar(); int x = 0, f = 1;
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar();
	}
	while ('0' <= ch && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar(); 
	} return x * f;
}


//NTT
int n, m, l, r[N];
int len = 1;
ll a[N], b[N];

inline ll qpow(ll a, ll b){
	ll res = 1;
	while(b){
		if(b & 1) res = (res * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	}
	return res % mod;
}

inline void NTT(ll a[], int inv){
	for(int i = 0; i < len; ++ i)
		if(i < r[i])
			swap(a[i], a[r[i]]);
	
	for(int mid = 1; mid < len; mid <<= 1){
		ll Wn = qpow(inv == 1 ? G : Gi , (mod - 1) / (mid << 1));
		for(int Size = mid << 1, L = 0; L < len; L += Size){
			ll w = 1;
			for(int i = 0; i < mid; ++ i, w = (w * Wn) % mod){
				int x = a[L + i], y = w * a[L + mid + i] % mod;
				a[L + i] = (x + y) % mod;
				a[L + mid + i] = (x - y + mod) % mod;
			}
		}
	}
}

int main()
{
	n = read(); m = read();
	for(int i = 0; i <= n; ++ i) a[i] = (read() + mod) % mod;
	for(int i = 0; i <= m; ++ i) b[i] = (read() + mod) % mod;
	
	while(len <= n + m) len <<= 1, l ++; 
	for(int i = 0; i < len; ++ i)
		r[i] = (r[i >> 1] >> 1 ) | ((i & 1) << (l - 1));
	
	NTT(a, 1); NTT(b, 1);
	for(int i = 0; i <= len; ++ i) a[i] = (a[i] * b[i]) % mod;
	NTT(a, -1);
	ll inv = qpow(len, mod - 2);
	for(int i = 0; i <= n + m; ++ i)
		printf("%d ", (a[i] * inv) % mod);
	return 0;
}

posted @ 2020-04-28 10:04  A_sc  阅读(126)  评论(0编辑  收藏  举报