結果
| 問題 |
No.2097 AND^k
|
| コンテスト | |
| ユーザー |
chro_96
|
| 提出日時 | 2022-11-09 20:58:54 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,235 bytes |
| コンパイル時間 | 539 ms |
| コンパイル使用メモリ | 34,176 KB |
| 実行使用メモリ | 163,632 KB |
| 最終ジャッジ日時 | 2024-07-23 02:19:36 |
| 合計ジャッジ時間 | 19,293 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 10 TLE * 1 -- * 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 (long long *a, long long root) {
int log = 0;
long long pow_root[32] = {};
while ((1<<log) < length) {
log++;
}
pow_root[log-1] = root;
for (int i = log-1; i > 0; i--) {
pow_root[i-1] = pow_root[i];
pow_root[i-1] *= pow_root[i];
pow_root[i-1] %= mod_num;
}
for (int i = 0; i < length; i++) {
int idx = 0;
int tmp = i;
for (int j = 0; j < log; j++) {
idx <<= 1;
idx |= (tmp&1);
tmp >>= 1;
}
if (i < idx) {
int swap = a[i];
a[i] = a[idx];
a[idx] = swap;
}
}
for (int i = 0; i < log; i++) {
int step = (1<<i);
int cnt = length/(2*step);
long long tmp_root = 1LL;
for (int j = 0; j < step; j++) {
for (int k = 0; k < cnt; k++) {
long long tmp1 = a[(k<<(i+1))+j];
long long tmp2 = (a[((2*k+1)<<i)+j]*tmp_root)%mod_num;
a[(k<<(i+1))+j] = (tmp1+tmp2)%mod_num;
a[((2*k+1)<<i)+j] = (tmp1+mod_num-tmp2)%mod_num;
}
tmp_root = (tmp_root*pow_root[i])%mod_num;
}
}
return;
}
int main () {
int n = 0;
int m = 0;
int l = 0;
int res = 0;
long long ans[300000] = {};
long long work[300000] = {};
long long pow2n = 0LL;
long long pow2[100001] = {};
long long fact[100001] = {};
long long invf[100001] = {};
long long ans_pow2[32][300000] = {};
long long ans_pow2_dft[32][300000] = {};
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);
ans_pow2[0][0] = pow2n;
for (int i = 1; i <= l; i++) {
ans_pow2[0][i] = invf[i];
}
for (int i = 0; i <= l; i++) {
ans_pow2_dft[0][i] = ans_pow2[0][i];
}
ntt_2n(ans_pow2_dft[0], root);
for (int i = 1; (1<<i) <= m; i++) {
long long p = 1LL;
for (int j = 0; j <= l; j++) {
ans_pow2[i][j] = ans_pow2[i-1][j];
ans_pow2[i][j] *= p;
ans_pow2[i][j] %= mod_num;
p = (p*pow2[1<<(i-1)])%mod_num;
}
ntt_2n(ans_pow2[i], root);
for (int j = 0; j < length; j++) {
ans_pow2[i][j] *= ans_pow2_dft[i-1][j];
ans_pow2[i][j] %= mod_num;
}
ntt_2n(ans_pow2[i], inverse_root);
for (int j = 0; j <= l; j++) {
ans_pow2[i][j] *= inverse_l;
ans_pow2[i][j] %= mod_num;
ans_pow2_dft[i][j] = ans_pow2[i][j];
}
ntt_2n(ans_pow2_dft[i], root);
}
ans[0] = 1LL;
for (int i = 0; (1<<i) <= m; i++) {
if ((m&(1<<i)) > 0) {
long long p = 1LL;
for (int j = 0; j <= l; j++) {
ans[j] = (ans[j]*p)%mod_num;
p = (p*pow2[1<<i])%mod_num;
}
ntt_2n(ans, root);
for (int j = 0; j < length; j++) {
ans[j] = (ans[j]*ans_pow2_dft[i][j])%mod_num;
}
ntt_2n(ans, inverse_root);
for (int i = 0; i <= l; i++) {
ans[i] *= inverse_l;
ans[i] %= mod_num;
}
for (int i = l+1; i < length; i++) {
ans[i] = 0LL;
}
}
}
for (int i = 0; i < l; i++) {
printf("%lld\n", (ans[i+1]*fact[i+1])%mod_num);
}
return 0;
}
chro_96