exp+ln 莫名WA一个点
查看原帖
exp+ln 莫名WA一个点
31656
lahlah楼主2020/7/1 13:58

调了一中午啊啊啊

多项式板子应该是没有问题,就是power里面不知道哪里写错了

code:

#include<bits/stdc++.h>
#define N 4000005
#define mod 998244353
#define ll long long
using namespace std;
int add(int x, int y) {
	x += y;
	if(x >= mod) x-= mod;
	return x;
}
int sub(int x, int y) {
	x -= y;
	if(x < 0) return x += mod;
	return x;
}
int mul(int x, int y) {
	return (ll)x * y % mod;
}
int qpow(int x, int y) {
	int ret = 1;
	for(; y; y >>= 1, x = mul(x, x)) if(y & 1) ret = mul(ret, x);
	return ret;
}
const int G = 3;
const int G_inv = qpow(G, mod - 2);
int rev[N];
void ntt(int *a, int n, int o) {
	for(int i = 1; i < n; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (n >> 1));
	for(int i = 1; i < n; i ++) if(i > rev[i]) swap(a[i], a[rev[i]]);
	for(int len = 2; len <= n; len <<= 1) {
		int w0 = qpow((o == 1)? G : G_inv, (mod - 1) / len);
		for(int i = 0; i < n; i += len) {
			int wn = 1;
			for(int j = i; j < i + (len >> 1); j ++, wn = mul(wn, w0)) {
				int X = a[j], Y = mul(wn, a[j + (len >> 1)]);
				a[j] = add(X, Y);
				a[j + (len >> 1)] = sub(X, Y);
			}
		}
	}
	int ninv = qpow(n, mod - 2);
	if(o == -1)
		for(int i = 0; i < n; i ++) a[i] = mul(a[i], ninv);
}
void Mul(int *a, int *b, int n, int m) {
	int len = 1;
	for(; len <= n + m; len <<= 1);
	ntt(a, len, 1), ntt(b, len, 1);
	for(int i = 0; i < len; i ++) a[i] = mul(a[i], b[i]);
	ntt(a, len, -1);
	for(int i = n + m; i <= len; i ++) a[i] = b[i] = 0;
}
int c[N], bb[N], bn[N], d[N];
void inv(int *a, int *b, int n) {
	if(n == 0) {b[0] = qpow(a[0], mod - 2); return;}
	inv(a, b, n / 2);
	int len = 1;
	for(; len <= n + n; len <<= 1);
	for(int i = 0; i <= n; i ++) c[i] = a[i];
	for(int i = n + 1; i <= len; i ++) c[i] = 0;
	ntt(c, len, 1), ntt(b, len, 1);
	for(int i = 0; i <= len; i ++) b[i] = sub(mul(b[i], 2), mul(b[i], mul(b[i], c[i])));
	ntt(b, len, -1);
	for(int i = n + 1; i <= len; i ++) b[i] = 0;	
} 
void qiudao(int *a, int n) {
	for(int i = 0; i < n; i ++) a[i] = mul((i + 1), a[i + 1]);
	a[n] = 0;
}
void jifen(int *a, int n) {
	for(int i = n; i >= 1; i --) a[i] = mul(qpow(i, mod - 2), a[i - 1]);
	a[0] = 0;
}
int ia[N], lnb[N];
void ln(int *a, int n) {
	inv(a, ia, n);
	qiudao(a, n);	
	Mul(a, ia, n, n);
	jifen(a, n);	
	for(int i = 0; i <= n; i ++) ia[i] = 0;
	for(int i = n + 1; i <= n + n + n; i ++) a[i] = ia[i] = 0;
}
void exp(int *a, int *b, int n) {
	if(n == 0) {b[0] = 1; return;}
	exp(a, b, n / 2);
	for(int i = 0; i <= n; i ++) lnb[i] = b[i]; 
	ln(lnb, n);
	lnb[0] = add(1, sub(a[0], lnb[0]));
	for(int i = 1; i <= n; i ++) lnb[i] = sub(a[i], lnb[i]);
	Mul(b, lnb, n, n);
	for(int i = n + 1; i <= n + n + n; i ++) b[i] = 0; 
	for(int i = 0; i <= n + n + n; i ++) lnb[i] = 0;
}
inline int read() {
	int x = 0;
	char ch = getchar();
	for(;ch < '0' || ch > '9';) ch = getchar();
	for(;ch >= '0' && ch <= '9';) x = add(mul(x, 10), ch - '0'), ch = getchar();
	return x; 
}
int ea[N];
void power(int *a, int n, int m1, int m2) {
	int pos = 0, c = 0;
	for(int i = 0; i <= n; i ++) if(a[i] != 0) {pos = i, c = a[i]; break;}
	int ic = qpow(c, mod - 2); c = qpow(c, m2);
	for(int i = 0; i <= n; i ++) a[i] = mul(a[i + pos], ic);
	ln(a, n);
	for(int i = 0; i <= n; i ++) a[i] = mul(a[i], m1);
	exp(a, ea, n);
	pos = min(pos * m1, n + 1);
	for(int i = 0; i < pos; i ++) a[i] = 0;
	for(int i = pos; i <= n; i ++) a[i] = mul(ea[i], c);
}
int a[N], b[N], n, m;
int main() {
	scanf("%d", &n); n --;
	
	int m1 = 0, m2 = 0, ws = 0;
	char ch = getchar();
	for(;ch < '0' || ch > '9';) ch = getchar();
	for(;ch >= '0' && ch <= '9';) m1 = add(mul(m1, 10), ch - '0'), m2 = ((ll)m2 * 10 + ch - '0') % (mod - 1), ch = getchar(), ws ++;
	for(int i = 0; i <= n; i ++) scanf("%d", &a[i]);	

	if(a[0] == 0 && ws >= 6) {
		for(int i = 0; i <= n; i ++) printf("0 ");
		return 0;
	}
	power(a, n, m1, m2);
	for(int i = 0; i <= n; i ++) printf("%d ", a[i]);
	return 0;
}

评测记录

2020/7/1 13:58
加载中...