結果
| 問題 |
No.3146 RE: Parentheses Counting
|
| コンテスト | |
| ユーザー |
shobonvip
|
| 提出日時 | 2025-05-16 22:24:18 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,956 bytes |
| コンパイル時間 | 4,616 ms |
| コンパイル使用メモリ | 264,288 KB |
| 実行使用メモリ | 85,512 KB |
| 最終ジャッジ日時 | 2025-05-16 22:25:39 |
| 合計ジャッジ時間 | 69,774 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 1 WA * 42 |
ソースコード
/**
author: shobonvip
created: 2025.05.16 21:46:58
**/
#include<bits/stdc++.h>
using namespace std;
//* ATCODER
#include<atcoder/all>
using namespace atcoder;
typedef modint998244353 mint;
//*/
/* BOOST MULTIPRECISION
#include<boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
//*/
typedef long long ll;
#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()
template <typename T> bool chmin(T &a, const T &b) {
if (a <= b) return false;
a = b;
return true;
}
template <typename T> bool chmax(T &a, const T &b) {
if (a >= b) return false;
a = b;
return true;
}
template <typename T> T max(vector<T> &a){
assert(!a.empty());
T ret = a[0];
for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
return ret;
}
template <typename T> T min(vector<T> &a){
assert(!a.empty());
T ret = a[0];
for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
return ret;
}
template <typename T> T sum(vector<T> &a){
T ret = 0;
for (int i=0; i<(int)a.size(); i++) ret += a[i];
return ret;
}
//defmodfact
const int COMinitMAX = 2198244;
mint fact[COMinitMAX+1], factinv[COMinitMAX+1];
void modfact(){
fact[0] = 1;
for (int i=1; i<=COMinitMAX; i++){
fact[i] = fact[i-1] * i;
}
factinv[COMinitMAX] = fact[COMinitMAX].inv();
for (int i=COMinitMAX-1; i>=0; i--){
factinv[i] = factinv[i+1] * (i+1);
}
}
mint cmb(int a, int b){
if (a<b || b<0) return mint(0);
return fact[a]*factinv[b]*factinv[a-b];
}
//--------
// Inv of Polynomial
// O(N log N)
// T should be modint
template<typename T>
std::vector<T> poly_inv(std::vector<T> &a, int M = -314159265){
if (M == -314159265) M = (int)a.size();
else if (M <= 0) return {};
int n = a.size();
T r = a[0].pow(T::mod()-2);
int m = 1;
std::vector<T> res = {r};
while (m < M){
std::vector<T> f = a;
f.resize(std::min(n, 2*m));
std::vector<T> h = atcoder::convolution(f, res);
for (int i=0; i<std::min(2*m, (int)h.size()); i++){
h[i] = -h[i];
}
h[0] += 2;
h.resize(2*m);
h = atcoder::convolution(h, res);
h.resize(2*m);
swap(res, h);
m <<= 1;
}
res.resize(M);
return res;
}
pair<vector<mint>, vector<mint>> poly_divmod(vector<mint> f, vector<mint> g){
if (f.size() < g.size()) return pair(vector<mint>(0), f);
int deg = (int)f.size() - (int)g.size() + 1;
vector<mint> rf = f;
reverse(rf.begin(), rf.end());
rf.resize(deg);
vector<mint> rg = g;
reverse(rg.begin(), rg.end());
rg.resize(deg);
rg = poly_inv(rg, deg);
vector<mint> q = convolution<mint>(rf, rg);
q.resize(deg);
reverse(q.begin(), q.end());
vector<mint> h = convolution<mint>(q, g);
vector<mint> r((int)f.size());
for (int i=0; i<(int)f.size(); i++){
r[i] = f[i] - h[i];
}
while((int)r.size() > 0 && r[(int)r.size() - 1] == 0) r.pop_back();
return pair(q, r);
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
modfact();
int n = 1000555;
vector<mint> f(n+2);
for (int i=2; i<=n+1; i+=2) {
f[i] += cmb(i-2,i/2-1)*fact[i/2-1]*factinv[i/2];
}
vector<mint> df(n+1);
for (int i=1; i<=n+1; i++) {
df[i-1] += f[i] * i;
}
vector<mint> g(n+2);
g[0] = 1;
for (int i=2; i<=n+1; i+=2) {
g[i] -= cmb(i-2,i/2-1)*fact[i/2-1]*factinv[i/2];
}
g = poly_inv(g);
vector<mint> dg(n+1);
for (int i=1; i<=n+1; i++) {
dg[i-1] += g[i] * i;
}
vector<mint> t1,t2;
for (int i=1; i<(int)dg.size(); i++) t1.push_back(dg[i]);
for (int i=1; i<(int)df.size(); i++) t2.push_back(df[i]);
vector<mint> h = convolution(t1, poly_inv(t2));
/*for (int i=0; i<=100; i++) {
cout << i << ' ' << h[i].val() << endl;
}*/
// h = sum f(x)^i * (i+1),
// original ... sum f(x)^i * (n/2-i)
// so, ans = - h[n] + (1+n/2) * [x^n] sum f(x)^i (which is g[n]).
vector<mint> ans(n + 1);
for (int i=2; i<=n; i+=2){
ans[i] = - h[i] + (1+i/2) * g[i];
}
int t; cin >> t;
while(t--) {
int v; cin >> v;
cout << ans[v].val() << '\n';
}
}
shobonvip