不是蒟蒻,不是萌新,多项式 ln 求助
  • 板块学术版
  • 楼主KokiNiwa
  • 当前回复15
  • 已保存回复15
  • 发布时间2020/6/24 22:14
  • 上次更新2023/11/7 00:07:29
查看原帖
不是蒟蒻,不是萌新,多项式 ln 求助
75715
KokiNiwa楼主2020/6/24 22:14

样例都过不去,好像是多项式求逆写挂了,但是不知道哪里挂了...

#include <cstdio>
#include <iostream>
using namespace std;
const int N = (1 << 18) + 5, mod = 998244353;
int n, poly[N], pinv[N], pln[N], g[25], invg[25], rev[N], tmpf[N];
int ml(int x, int y) { return 1ll * x * y % mod; }
int ad(int x, int y) { return (x + y > mod) ? (x + y - mod) : (x + y); }
int dc(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
int ksm(int x, int y) {
	int ret = 1;
	for (; y; y >>= 1, x = ml(x, x))
		if (y & 1)
			ret = ml(ret, x);
	return ret;
}
void Init() {
	for (int i = 0; i <= 23; ++i) g[i] = ksm(3, (mod - 1) >> i);
	for (int i = 0; i <= 23; ++i) invg[i] = ksm(g[i], mod - 2);
}
void GetRev(int deg) {
	for (int i = 1; i < deg; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (deg >> 1) : 0);
}
void NTT(int *poly, int type, int deg) {
	for (int i = 0; i < deg; ++i)
		if (rev[i] < i)
			swap(poly[i], poly[rev[i]]);
	int cnt = 1;
	for (int len = 2; len <= deg; ++len) {
		int gen = (type > 0) ? g[cnt] : invg[cnt], half = len >> 1;
		for (int bg = 0; bg < deg; bg += len) {
			int now = 1;
			for (int pos = bg; pos < bg + half; ++pos) {
				int tmp = ml(poly[pos + half], now);
				poly[pos + half] = dc(poly[pos], tmp);
				poly[pos] = ad(poly[pos], tmp);
				now = ml(now, gen);
			}
		}
		++cnt;
	}
	if (type < 0) {
		int inv = ksm(deg, mod - 2);
		for (int i = 0; i < deg; ++i) poly[i] = ml(poly[i], inv);
	}
}
void PolyInv(const int *f, int *ans, int deg) {
	if (deg == 1) {
		ans[0] = ksm(f[0], mod - 2);
		return;
	}
	PolyInv(f, ans, deg >> 1);
	for (int i = 0; i < deg; ++i) tmpf[i] = f[i];
	for (int i = deg; i < (deg << 1); ++i) tmpf[i] = 0;
	GetRev(deg << 1);
	NTT(ans, 1, deg << 1);
	NTT(tmpf, 1, deg << 1);
	for (int i = 0; i < (deg << 1); ++i) ans[i] = dc(ml(2, ans[i]), ml(ml(tmpf[i], ans[i]), ans[i]));
	NTT(ans, -1, deg << 1);
	for (int i = deg; i < (deg << 1); ++i) ans[i] = 0;
}
void PolyDer(const int *f, int *ans, int len) {
	for (int i = 0; i < len; ++i) ans[i] = ml(f[i + 1], i + 1);
}
void PolyInt(const int *f, int *ans, int len) {
	for (int i = 0; i < len; ++i) ans[i + 1] = ml(f[i], ksm(i + 1, mod - 2));
}
void PolyLn(const int *f, int *ans, int deg) {
	int up = 1;
	while (up <= deg) up <<= 1;
	GetRev(up);
	PolyDer(f, tmpf, deg);
	PolyInv(f, ans, up);
	for (int i = 0; i < up; ++i)
		printf("i : %d ans[i] : %d\n", i, ans[i]);
	NTT(tmpf, 1, up);
	NTT(ans, 1, up);
	for (int i = 0; i < up; ++i) ans[i] = ml(ans[i], tmpf[i]);
	NTT(ans, -1, up);
	for (int i = 0; i < up; ++i) tmpf[i] = ans[i];
	PolyInt(tmpf, ans, deg);
}
int main() {
	scanf("%d", &n);
	--n;
	for (int i = 0; i <= n; ++i) scanf("%d", &poly[i]);
	Init();
	PolyLn(poly, pln, n);
	for (int i = 0; i <= n; ++i) printf("%d ", pln[i]);
	printf("\n");
	return 0;
}
/*
10
1 998244352 998244352 0 0 0 0 0 0 0
*/
```cpp
2020/6/24 22:14
加载中...