提出 #34934794


ソースコード 拡げる

#include <bits/stdc++.h>

using namespace std;

const int mod = 998244353;

inline void uadd(int &x, int y)
{
	x += y - mod;
	x += x >> 31 & mod;
}

inline void umul(int &x, int y)
{
	x = 1LL * x * y % mod;
}

inline int add(int x, int y)
{
	return x + y < mod ? x + y : x + y - mod;
}

inline int mul(int x, int y)
{
	return 1LL * x * y % mod;
}

inline int qpow(int x, int n)
{
	int ans = 1;
	for (; n; n >>= 1, umul(x, x))
	{
		if (n & 1) umul(ans, x);
	}
	return ans;
}

namespace FFT
{
	const int mxn = 1 << 18;
	int N;
	int r[mxn];
	int w[mxn];
	
	void init(int n)
	{
		if (N == n) return;
		N = n;
		for (int i = 1; i < n - 1; ++ i)
		{
			r[i] = r[i >> 1] >> 1 | (i & 1 ? n >> 1 : 0);
		}
		for (int h = 1; h < n; h <<= 1)
		{
			int temp = qpow(3, (mod - 1) / (h << 1));
			for (int i = 0; i < h; ++ i)
			{
				w[h + i] = i ? mul(w[h + i - 1], temp) : 1;
			}
		}
	}
	
	void dft(int a[], int n)
	{
		init(n);
		for (int i = 1; i < n - 1; ++ i)
		{
			if (i < r[i]) swap(a[i], a[r[i]]);
		}
		for (int h = 1; h < n; h <<= 1)
			for (int i = 0; i < n; i += h << 1)
				for (int j = 0; j < h; ++ j)
				{
					int v = mul(a[i + h + j], w[h + j]);
					a[i + h + j] = add(a[i + j], mod - v);
					uadd(a[i + j], v);
				}
	}
	
	void idft(int a[], int n)
	{
		dft(a, n);
		reverse(a + 1, a + n);
		int iv = qpow(n, mod - 2);
		for (int i = 0; i < n; ++ i) umul(a[i], iv);
	}
}

struct Poly : vector <int>
{
	Poly() { clear(); }
	Poly(size_t n) { assign(n, 0); }
	Poly(vector <int> v) { clear(); for (int x : v) push_back(x); }
	Poly(initializer_list <int> v) { clear(); for (int x : v) push_back(x); }
	
	friend Poly operator + (const Poly &a, const Poly &b)
	{
		Poly c(max(a.size(), b.size()));
		for (int i = 0; i < (int) a.size(); ++ i) uadd(c[i], a[i]);
		for (int i = 0; i < (int) b.size(); ++ i) uadd(c[i], b[i]);
		return c;
	}
	
	friend Poly operator - (const Poly &a, const Poly &b)
	{
		Poly c(max(a.size(), b.size()));
		for (int i = 0; i < (int) a.size(); ++ i) uadd(c[i], a[i]);
		for (int i = 0; i < (int) b.size(); ++ i) uadd(c[i], mod - b[i]);
		return c;
	}
	
	friend Poly operator * (const Poly &a, const Poly &b)
	{
		Poly c(a.size() + b.size() - 1);
		int sz = 1;
		for (; sz < (int) c.size(); sz <<= 1) ;
		if (1LL * a.size() * b.size() <= 32LL * sz)
		{
			for (int i = 0; i < (int) a.size(); ++ i)
				for (int j = 0; j < (int) b.size(); ++ j)
					uadd(c[i + j], mul(a[i], b[j]));
		}
		else
		{
			static int A[FFT::mxn], B[FFT::mxn];
			for (int i = 0; i < sz; ++ i) A[i] = i < (int) a.size() ? a[i] : 0;
			for (int i = 0; i < sz; ++ i) B[i] = i < (int) b.size() ? b[i] : 0;
			FFT::dft(A, sz);
			FFT::dft(B, sz);
			for (int i = 0; i < sz; ++ i) umul(A[i], B[i]);
			FFT::idft(A, sz);
			for (int i = 0; i < (int) c.size(); ++ i) c[i] = A[i];
		}
		return c;
	}
};

struct Func // kx + b
{
	Poly k, b;
	
	Func operator () (Func f) const
	{
		return {k * f.k, k * f.b + b};
	}
	Poly operator () (Poly f) const
	{
		return k * f + b;
	}
};

const int mxn = 2e5 + 5;

int n;
vector <int> adj[mxn];
int fa[mxn], sz[mxn], son[mxn];

void dfs(int u)
{
	sz[u] = 1, son[u] = 0;
	for (int v : adj[u]) if (v != fa[u])
	{
		fa[v] = u;
		dfs(v);
		sz[u] += sz[v];
		if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
	}
}

Poly solve(int);

Poly conq2(vector <int> &vec, int l, int r)
{
	if (l > r) return {1};
	if (l == r) return solve(vec[l]);
	int m = l;
	auto wei = [&] (int u)
	{
		return sz[u];
	};
	int Sl = 0, Sr = 0;
	for (int i = l; i <= r; ++ i) Sr += wei(vec[i]);
	while (Sl + wei(vec[m]) < Sr - wei(vec[m]))
	{
		Sl += wei(vec[m]), Sr -= wei(vec[m]);
		++ m;
	}
	return conq2(vec, l, m - 1) * conq2(vec, m, m) * conq2(vec, m + 1, r);
}

Func conq1(vector <int> &vec, int l, int r)
{
	if (l > r) return {{1}, {0}};
	if (l == r)
	{
		int u = vec[l];
		vector <int> lson;
		for (int v : adj[u]) if (v != fa[u] && v != son[u])
			lson.push_back(v);
		return {conq2(lson, 0, (int) lson.size() - 1), {0, 1}};
	}
	int m = l;
	auto wei = [&] (int u)
	{
		return sz[u] - sz[son[u]];
	};
	int Sl = 0, Sr = 0;
	for (int i = l; i <= r; ++ i) Sr += wei(vec[i]);
	while (Sl + wei(vec[m]) < Sr - wei(vec[m])) 
	{
		Sl += wei(vec[m]), Sr -= wei(vec[m]);
		++ m;
	}
	return conq1(vec, l, m - 1)(conq1(vec, m, m)(conq1(vec, m + 1, r)));
}

Poly solve(int u)
{
	vector <int> chain;
	for (int x = u; x; x = son[x]) chain.push_back(x);
	return conq1(chain, 0, (int) chain.size() - 1)((Poly){1});
}

int main()
{
	ios::sync_with_stdio(0);
	cin >> n;
	for (int i = 2; i <= n; ++ i)
	{
		int p;
		cin >> p;
		adj[p].push_back(i);
	}
	dfs(1);
	Poly p = solve(1);
	for (int k = 1; k <= n; ++ k)
		cout << (k < (int) p.size() ? p[k] : 0) << "\n";
	return 0;
}

提出情報

提出日時
問題 Ex - Antichain
ユーザ bmb87978
言語 C++ (GCC 9.2.1)
得点 600
コード長 4902 Byte
結果 AC
実行時間 566 ms
メモリ 33236 KiB

コンパイルエラー

./Main.cpp: In function ‘Poly operator*(const Poly&, const Poly&)’:
./Main.cpp:117:33: warning: comparison of integer expressions of different signedness: ‘long long unsigned int’ and ‘long long int’ [-Wsign-compare]
  117 |   if (1LL * a.size() * b.size() <= 32LL * sz)
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 600 / 600
結果
AC × 4
AC × 38
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 02_path_00.txt, 03_star_00.txt, 03_star_01.txt, 03_star_02.txt, 03_star_03.txt, 04_centipede_00.txt, 04_centipede_01.txt, 04_centipede_02.txt, 04_centipede_03.txt, 04_centipede_04.txt, 04_centipede_05.txt, 04_centipede_06.txt, 04_centipede_07.txt, 04_centipede_08.txt, 04_centipede_09.txt, 04_centipede_10.txt, 04_centipede_11.txt, 05_n-ary_00.txt, 05_n-ary_01.txt, 05_n-ary_02.txt, 05_n-ary_03.txt, 05_n-ary_04.txt, 05_n-ary_05.txt, 05_n-ary_06.txt, 06_corner_00.txt, 07_theta_n_log_3_n_00.txt, 07_theta_n_log_3_n_01.txt, 07_theta_n_log_3_n_02.txt, 07_theta_n_log_3_n_03.txt, 07_theta_n_log_3_n_04.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 10 ms 8260 KiB
00_sample_01.txt AC 10 ms 8236 KiB
00_sample_02.txt AC 9 ms 8180 KiB
00_sample_03.txt AC 9 ms 8292 KiB
01_random_00.txt AC 83 ms 10524 KiB
01_random_01.txt AC 193 ms 14580 KiB
01_random_02.txt AC 181 ms 14200 KiB
01_random_03.txt AC 163 ms 14276 KiB
02_path_00.txt AC 97 ms 33236 KiB
03_star_00.txt AC 163 ms 15032 KiB
03_star_01.txt AC 298 ms 20172 KiB
03_star_02.txt AC 299 ms 19824 KiB
03_star_03.txt AC 298 ms 19732 KiB
04_centipede_00.txt AC 219 ms 29204 KiB
04_centipede_01.txt AC 278 ms 29484 KiB
04_centipede_02.txt AC 273 ms 26304 KiB
04_centipede_03.txt AC 310 ms 26872 KiB
04_centipede_04.txt AC 517 ms 23076 KiB
04_centipede_05.txt AC 566 ms 22284 KiB
04_centipede_06.txt AC 543 ms 21920 KiB
04_centipede_07.txt AC 544 ms 23272 KiB
04_centipede_08.txt AC 260 ms 24008 KiB
04_centipede_09.txt AC 259 ms 23668 KiB
04_centipede_10.txt AC 276 ms 22284 KiB
04_centipede_11.txt AC 276 ms 22636 KiB
05_n-ary_00.txt AC 313 ms 18328 KiB
05_n-ary_01.txt AC 367 ms 21388 KiB
05_n-ary_02.txt AC 389 ms 20992 KiB
05_n-ary_03.txt AC 359 ms 19760 KiB
05_n-ary_04.txt AC 381 ms 20064 KiB
05_n-ary_05.txt AC 421 ms 19792 KiB
05_n-ary_06.txt AC 494 ms 20136 KiB
06_corner_00.txt AC 275 ms 26404 KiB
07_theta_n_log_3_n_00.txt AC 413 ms 19036 KiB
07_theta_n_log_3_n_01.txt AC 393 ms 18728 KiB
07_theta_n_log_3_n_02.txt AC 392 ms 19252 KiB
07_theta_n_log_3_n_03.txt AC 367 ms 19776 KiB
07_theta_n_log_3_n_04.txt AC 339 ms 20288 KiB