結果
| 問題 |
No.2097 AND^k
|
| コンテスト | |
| ユーザー |
chro_96
|
| 提出日時 | 2022-10-21 20:58:14 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,596 bytes |
| コンパイル時間 | 311 ms |
| コンパイル使用メモリ | 34,012 KB |
| 実行使用メモリ | 22,540 KB |
| 最終ジャッジ日時 | 2024-07-01 05:52:47 |
| 合計ジャッジ時間 | 25,504 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 9 TLE * 2 -- * 12 |
ソースコード
#include <stdio.h>
long long mod_num = 998244353LL;
long long root = 3LL;
int length = 998244352;
long long inverse_root = 0LL;
long long inverse_l = 0LL;
long long power_mod (long long a, long long b, long long p) {
long long ans = 0LL;
a %= p;
if (b <= 0LL) {
return 1LL;
}
ans = power_mod(a, b/2LL, p);
ans = (ans * ans) % p;
if (b%2LL == 1LL) {
ans = (ans * a) % p;
}
return ans;
}
void setup_ntt (int l) {
int tmp_length = 2;
while(tmp_length < 2*l) {
tmp_length *= 2;
}
root = power_mod(root, length / tmp_length, mod_num);
inverse_root = power_mod(root, mod_num-2LL, mod_num);
inverse_l = power_mod((long long) tmp_length, mod_num-2LL, mod_num);
length = tmp_length;
return;
}
void ntt_2n_bit_inverse_rec (long long *a, long long root, int l) {
long long next_root = (root*root)%mod_num;
long long alpha = 1LL;
if (l <= 1) {
return;
}
for (int i = 0; i < l/2; i++) {
a[i] = (a[i] + a[i+l/2]) % mod_num;
a[i+l/2] = (a[i] + mod_num - ((2LL * a[i+l/2]) % mod_num)) % mod_num;
a[i+l/2] = (alpha * a[i+l/2]) % mod_num;
alpha = (alpha * root) % mod_num;
}
ntt_2n_bit_inverse_rec(a, next_root, l/2);
ntt_2n_bit_inverse_rec(a+l/2, next_root, l/2);
return;
}
void ntt_2n (long long *a, long long *work, long long root, int l) {
for (int i = 0; i < l; i++) {
work[i] = a[i];
}
ntt_2n_bit_inverse_rec(work, root, l);
for (int i = 0; i < l; i++) {
int j = 0;
int b = l / 2;
int rem = i;
while (rem > 0) {
j += b * (rem%2);
b /= 2;
rem /= 2;
}
a[j] = work[i];
}
return;
}
void conv_mod (long long *a1, long long *a2, long long *ans, long long *work1, long long *work2) {
for(int i = 0; i < length; i++) {
work1[i] = a1[i];
work2[i] = a2[i];
}
ntt_2n(work1, ans, root, length);
ntt_2n(work2, ans, root, length);
for(int i = 0; i < length; i++) {
ans[i] = (work1[i] * work2[i]) % mod_num;
}
ntt_2n(ans, work1, inverse_root, length);
for(int i = 0; i < length; i++) {
ans[i] = (ans[i] * inverse_l) % mod_num;
}
return;
}
void func (int m, int l, long long *ans, long long *work1, long long *work2, long long *work3, long long *work4, long long pow2n, long long *pow2, long long *fact, long long *invf) {
long long pow = 1LL;
if (m < 1) {
ans[0] = 1LL;
for (int i = 1; i < length; i++) {
ans[i] = 0LL;
}
return;
}
func(m/2, l, ans, work1, work2, work3, work4, pow2n, pow2, fact, invf);
for (int i = 0; i <= l; i++) {
long long tmp = (ans[i]*invf[i])%mod_num;
work1[i] = tmp;
work2[i] = (tmp*pow)%mod_num;
pow = (pow*pow2[m/2])%mod_num;
}
for (int i = l+1; i < length; i++) {
work1[i] = 0LL;
work2[i] = 0LL;
}
conv_mod(work1, work2, ans, work3, work4);
for (int i = 0; i <= l; i++) {
ans[i] *= fact[i];
ans[i] %= mod_num;
}
for (int i = l+1; i < length; i++) {
ans[i] = 0LL;
}
if (m%2 == 1) {
pow = pow2[m-1];
for (int i = 0; i <= l; i++) {
work1[i] = (ans[i]*invf[i])%mod_num;
}
work2[0] = pow2n;
for (int i = 1; i <= l; i++) {
work2[i] = (pow*invf[i])%mod_num;
pow = (pow*pow2[m-1])%mod_num;
}
for (int i = l+1; i < length; i++) {
work1[i] = 0LL;
work2[i] = 0LL;
}
conv_mod(work1, work2, ans, work3, work4);
for (int i = 0; i <= l; i++) {
ans[i] *= fact[i];
ans[i] %= mod_num;
}
for (int i = l+1; i < length; i++) {
ans[i] = 0LL;
}
}
return;
}
int main () {
int n = 0;
int m = 0;
int l = 0;
int res = 0;
long long ans[300000] = {};
long long work[4][300000] = {};
long long pow2n = 0LL;
long long pow2[100001] = {};
long long fact[100001] = {};
long long invf[100001] = {};
res = scanf("%d", &n);
res = scanf("%d", &m);
res = scanf("%d", &l);
pow2n = power_mod(2LL, (long long)n, mod_num);
pow2[0] = 1LL;
for (int i = 0; i < m; i++) {
pow2[i+1] = (pow2[i]*2LL)%mod_num;
}
fact[0] = 1LL;
for (int i = 0; i < l; i++) {
fact[i+1] = fact[i];
fact[i+1] *= (long long) (i+1);
fact[i+1] %= mod_num;
}
invf[l] = power_mod(fact[l], mod_num-2LL, mod_num);
for (int i = l; i > 0; i--) {
invf[i-1] = invf[i];
invf[i-1] *= (long long)i;
invf[i-1] %= mod_num;
}
setup_ntt(l+1);
func(m, l, ans, work[0], work[1], work[2], work[3], pow2n, pow2, fact, invf);
for (int i = 0; i < l; i++) {
printf("%lld\n", ans[i+1]);
}
return 0;
}
chro_96