結果
問題 |
No.1684 Find Brackets
|
ユーザー |
|
提出日時 | 2025-07-10 15:38:50 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 503 ms / 2,000 ms |
コード長 | 15,768 bytes |
コンパイル時間 | 4,705 ms |
コンパイル使用メモリ | 270,924 KB |
実行使用メモリ | 11,440 KB |
最終ジャッジ日時 | 2025-07-10 15:39:03 |
合計ジャッジ時間 | 11,691 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 21 |
ソースコード
#ifndef HIDDEN_IN_VS // 折りたたみ用 // 警告の抑制 #define _CRT_SECURE_NO_WARNINGS // ライブラリの読み込み #include <bits/stdc++.h> using namespace std; // 型名の短縮 using ll = long long; using ull = unsigned long long; // -2^63 ~ 2^63 = 9e18(int は -2^31 ~ 2^31 = 2e9) using pii = pair<int, int>; using pll = pair<ll, ll>; using pil = pair<int, ll>; using pli = pair<ll, int>; using vi = vector<int>; using vvi = vector<vi>; using vvvi = vector<vvi>; using vvvvi = vector<vvvi>; using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>; using vvvvl = vector<vvvl>; using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>; using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>; using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>; template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>; using Graph = vvi; // 定数の定義 const double PI = acos(-1); int DX[4] = { 1, 0, -1, 0 }; // 4 近傍(下,右,上,左) int DY[4] = { 0, 1, 0, -1 }; int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF; // 入出力高速化 struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp; // 汎用マクロの定義 #define all(a) (a).begin(), (a).end() #define sz(x) ((int)(x).size()) #define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x))) #define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x))) #define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");} #define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順 #define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順 #define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順 #define repe(v, a) for(const auto& v : (a)) // a の全要素(変更不可能) #define repea(v, a) for(auto& v : (a)) // a の全要素(変更可能) #define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索(昇順) #define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素(昇順) #define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て(昇順) #define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去 #define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了 #define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定 // 汎用関数の定義 template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; } template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新(更新されたら true を返す) template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新(更新されたら true を返す) template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); } template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod // 演算子オーバーロード template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; } template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; } template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; } template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; } #endif // 折りたたみ用 #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #ifdef _MSC_VER #include "localACL.hpp" #endif //using mint = modint998244353; using mint = static_modint<(int)1e9+7>; //using mint = modint; // mint::set_mod(m); using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>; #endif #ifdef _MSC_VER // 手元環境(Visual Studio) #include "local.hpp" #else // 提出用(gcc) int mute_dump = 0; int frac_print = 0; #if __has_include(<atcoder/all>) namespace atcoder { inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; } inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; } } #endif inline int popcount(int n) { return __builtin_popcount(n); } inline int popcount(ll n) { return __builtin_popcountll(n); } inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; } inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; } inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; } inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; } #define dump(...) #define dumpel(v) #define dump_math(v) #define input_from_file(f) #define output_to_file(f) #define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す #endif //【部分集合の全探索(大きさ固定)】O(nCr) /* * 大きさ n の全体集合 Ω のうち,大きさ r の部分集合 set⊂Ω を昇順に全探索する. * * 制約:r > 0 */ // verify : https://onlinejudge.u-aizu.ac.jp/courses/lesson/8/ITP2/all/ITP2_11_D #define repbc(set, n, r) for(int set = (1 << int(r)) - 1, lb, nx; set < (1 << int(n)); lb = set & -set, nx = set + lb, set = (((set & ~nx) / lb) >> 1) | nx) ll naive(int n, int m) { if (m == 0) return 2 * n; ll res = 0; repbc(set, n, m) { vi acc(n + 1); rep(i, n) acc[i + 1] = acc[i] + (getb(set, i) ? 1 : -1); int acc_min = *min_element(all(acc)); res += (acc[0] - acc_min) + n + (acc[n] - acc_min); } return res; } void zikken() { int N = 28; vvl tbl(N); repi(n, 1, N) { tbl[n - 1].resize(n); repi(m, 1, n) { dump(n, m); tbl[n - 1][m - 1] = naive(n, m); } } dumpel(tbl); dump_math(tbl); exit(0); } /* 0: 2 1: 6 4 2: 14 14 6 3: 26 34 26 8 4: 42 72 72 42 10 5: 62 134 164 134 62 12 6: 86 226 338 338 226 86 14 7: 114 354 634 746 634 354 114 16 8: 146 524 1100 1520 1520 1100 524 146 18 9: 182 742 1792 2872 3292 2872 1792 742 182 20 10: 222 1014 2774 5084 6668 6668 5084 2774 1014 222 22 11: 266 1346 4118 8518 12676 14260 12676 8518 4118 1346 266 24 12: 314 1744 5904 13626 22778 28784 28784 22778 13626 5904 1744 314 26 13: 366 2214 8220 20960 38978 54994 61000 54994 38978 20960 8220 2214 366 28 14: 422 2762 11162 31182 63942 99978 122858 122858 99978 63942 31182 11162 2762 422 30 15: 482 3394 14834 45074 101130 173930 235706 258586 235706 173930 101130 45074 14834 3394 482 32 16: 546 4116 19348 63548 154940 291076 432516 520032 520032 432516 291076 154940 63548 19348 4116 546 34 17: 614 4934 24824 87656 230864 470768 762488 1001168 1088684 1001168 762488 470768 230864 87656 24824 4934 614 36 18: 686 5854 31390 118600 335656 738760 1296904 1851172 2187092 2187092 1851172 1296904 738760 335656 118600 31390 5854 686 38 19: 762 6882 39182 157742 477512 1128680 2136440 3299240 4223020 4558940 4223020 3299240 2136440 1128680 477512 157742 39182 6882 762 40 20: 842 8024 48344 206614 666262 1683712 3420160 5687620 7858180 9151472 9151472 7858180 5687620 3420160 1683712 666262 206614 48344 8024 842 42 21: 926 9286 59028 266928 913574 2458502 5336432 9514760 14133660 17715084 19008376 17715084 14133660 9514760 5336432 2458502 913574 266928 59028 9286 926 44 22: 1014 10674 71394 340586 1233170 3521302 8136022 15490732 24643260 33142036 38134324 38134324 33142036 24643260 15490732 8136022 3521302 1233170 340586 71394 10674 1014 46 23: 1106 12194 85610 429690 1641054 4956366 12147638 24607382 41768372 60073428 73980516 78972804 73980516 60073428 41768372 24607382 12147638 4956366 1641054 429690 85610 12194 1106 48 24: 1202 13852 101852 536552 2155752 6866612 17796212 38225962 68990762 105764312 139046232 158361632 158361632 139046232 105764312 68990762 38225962 17796212 6866612 2155752 536552 101852 13852 1202 50 25: 1302 15654 120304 663704 2798564 9376564 25624224 58185324 111302674 181292594 253725344 307808464 327123864 307808464 253725344 181292594 111302674 58185324 25624224 9376564 2798564 663704 120304 15654 1302 52 26: 1406 17606 141158 813908 3593828 12635588 36316388 86934098 175737098 303218738 450470258 580849208 655733528 655733528 580849208 450470258 303218738 175737098 86934098 36316388 12635588 3593828 813908 141158 17606 1406 54 27: 1514 19714 164614 990166 4569196 16821436 50728036 127690636 272044846 495828406 779764786 1066087186 1276699336 1351583656 1276699336 1066087186 779764786 495828406 272044846 127690636 50728036 16821436 4569196 990166 164614 19714 1514 56 {{2},{6,4},{14,14,6},{26,34,26,8},{42,72,72,42,10},{62,134,164,134,62,12},{86,226,338,338,226,86,14},{114,354,634,746,634,354,114,16},{146,524,1100,1520,1520,1100,524,146,18},{182,742,1792,2872,3292,2872,1792,742,182,20},{222,1014,2774,5084,6668,6668,5084,2774,1014,222,22},{266,1346,4118,8518,12676,14260,12676,8518,4118,1346,266,24},{314,1744,5904,13626,22778,28784,28784,22778,13626,5904,1744,314,26},{366,2214,8220,20960,38978,54994,61000,54994,38978,20960,8220,2214,366,28},{422,2762,11162,31182,63942,99978,122858,122858,99978,63942,31182,11162,2762,422,30},{482,3394,14834,45074,101130,173930,235706,258586,235706,173930,101130,45074,14834,3394,482,32},{546,4116,19348,63548,154940,291076,432516,520032,520032,432516,291076,154940,63548,19348,4116,546,34},{614,4934,24824,87656,230864,470768,762488,1001168,1088684,1001168,762488,470768,230864,87656,24824,4934,614,36},{686,5854,31390,118600,335656,738760,1296904,1851172,2187092,2187092,1851172,1296904,738760,335656,118600,31390,5854,686,38},{762,6882,39182,157742,477512,1128680,2136440,3299240,4223020,4558940,4223020,3299240,2136440,1128680,477512,157742,39182,6882,762,40},{842,8024,48344,206614,666262,1683712,3420160,5687620,7858180,9151472,9151472,7858180,5687620,3420160,1683712,666262,206614,48344,8024,842,42},{926,9286,59028,266928,913574,2458502,5336432,9514760,14133660,17715084,19008376,17715084,14133660,9514760,5336432,2458502,913574,266928,59028,9286,926,44},{1014,10674,71394,340586,1233170,3521302,8136022,15490732,24643260,33142036,38134324,38134324,33142036,24643260,15490732,8136022,3521302,1233170,340586,71394,10674,1014,46},{1106,12194,85610,429690,1641054,4956366,12147638,24607382,41768372,60073428,73980516,78972804,73980516,60073428,41768372,24607382,12147638,4956366,1641054,429690,85610,12194,1106,48},{1202,13852,101852,536552,2155752,6866612,17796212,38225962,68990762,105764312,139046232,158361632,158361632,139046232,105764312,68990762,38225962,17796212,6866612,2155752,536552,101852,13852,1202,50},{1302,15654,120304,663704,2798564,9376564,25624224,58185324,111302674,181292594,253725344,307808464,327123864,307808464,253725344,181292594,111302674,58185324,25624224,9376564,2798564,663704,120304,15654,1302,52},{1406,17606,141158,813908,3593828,12635588,36316388,86934098,175737098,303218738,450470258,580849208,655733528,655733528,580849208,450470258,303218738,175737098,86934098,36316388,12635588,3593828,813908,141158,17606,1406,54},{1514,19714,164614,990166,4569196,16821436,50728036,127690636,272044846,495828406,779764786,1066087186,1276699336,1351583656,1276699336,1066087186,779764786,495828406,272044846,127690636,50728036,16821436,4569196,990166,164614,19714,1514,56}}; これを 2D P-recursive チェッカーにぶち込みコードを自動生成する. 0 除算で漸化式が使えないところがあるが,対称性を利用して解決する. */ int main() { // input_from_file("input.txt"); // output_to_file("output.txt"); // zikken(); int n, m; cin >> n >> m; vm dp(n + 1); auto Power = [&](const mint& x, int n) { mint res = 1; rep(hoge, n) res *= x; return res; }; { dp[0] = 2 * n; } { mint nn1 = n; dp[1] = 2 * (1 - nn1 + Power(nn1, 2)); } { vm dp2{ -1, 4, 14, 34, 72, 134, 226, 354, 524, 742, 1014, 1346, 1744, 2214, \ 2762, 3394, 4116, 4934, 5854, 6882, 8024, 9286, 10674, 12194, 13852, \ 15654, 17606, 19714 }; dp2.resize(n + 1); { auto dpsub1 = [&](const mint& x) { return dp2[x.val()]; }; repi(i, 5, n) { mint nn = i; dp2[i] = ((-3 + nn) * (5 + 2 * nn) * dpsub1(-2 + nn) + (33 + nn * (8 + 5 * nn)) * dpsub1(-1 + nn)) / (39 + nn * (-20 + 7 * nn)); } } dp[2] = dp2[n - 1]; } { vm dp2{ -1, 6, 26, 72, 164, 338, 634, 1100, 1792, 2774, 4118, 5904, 8220, 11162, \ 14834, 19348, 24824, 31390, 39182, 48344, 59028, 71394, 85610, \ 101852, 120304, 141158, 164614 }; dp2.resize(n + 1); { auto dpsub1 = [&](const mint& x) { return dp2[x.val()]; }; repi(i, 5, n) { mint nn = i; dp2[i] = (-8 * (-5 + nn) * nn * dpsub1(-3 + nn) + (168 + (-62 + nn) * nn) * dpsub1(-2 + nn) + (4 + nn * (-53 + 12 * nn)) * dpsub1(-1 + nn)) / (44 + 5 * (-7 + nn) * nn); } } dp[3] = dp2[n - 2]; } auto dpsub = [&](const mint& x, const mint& y) { return dp[y.val()]; }; // 0 除算の発生しないギリギリまでは漸化式で埋める. repi(i, 4, n / 2) { mint nn1 = n; mint nn2 = i; dp[i] = -(((700581974 * Power(nn1, 6) + Power(nn1, 5) * (-2491270481 + 994180316 * nn2) + Power(nn1, 4) * (4752959221 - 3572746162 * nn2 + 723860738 * Power(nn2, 2)) + Power(nn1, 3) * (-8334138866 + 2 * nn2 * (4023081423 + nn2 * (-1380696345 + 174393361 * nn2))) + (-3 + nn2) * (-2 + nn2) * (1813967271 + nn2 * (-9058196973 + nn2 * (7081475723 + nn2 * (-2046557542 + 209311507 * nn2)))) + Power(nn1, 2) * (46081673365 + nn2 * (-68335126131 + nn2 * (38172371942 + nn2 * (-9384099669 + 860524792 * nn2)))) + nn1 * (1244427029 + nn2 * (7446734673 + nn2 * (-11620733324 + nn2 * (6661865864 + nn2 * (-1697376082 + 162753979 * nn2)))))) * dpsub(nn1, -3 + nn2) + (299418033 * Power(nn1, 6) + Power(nn1, 5) * (-1107565606 + 604655757 * nn2) + Power(nn1, 4) * (1863335960 + 3 * nn2 * (-884674820 + 295538239 * nn2)) + Power(-2 + nn2, 2) * (-1 + nn2) * (2197672139 + nn2 * (-383704868 + 209311507 * (-3 + nn2) * nn2)) + Power(nn1, 3) * (-4380893735 + 2 * nn2 * (3776237978 + nn2 * (-2142483759 + 406983632 * nn2))) + nn1 * (-2 + nn2) * (3808147594 + nn2 * (-9994180379 + nn2 * (9732491653 + nn2 * (-3930163736 + 581376993 * nn2)))) + Power(nn1, 2) * (4523180111 + nn2 * (-10322499498 + nn2 * (9787680033 + nn2 * (-3988360646 + 604655757 * nn2))))) * dpsub(nn1, -2 + nn2) + (-1 + nn2) * (401163941 * Power(nn1, 5) + Power(nn1, 4) * (616295139 + 90106526 * nn2) + Power(nn1, 3) * (284967490 + nn2 * (-308246254 + 232590271 * nn2)) + Power(nn1, 2) * (-395146881 + nn2 * (1688547861 - 941605728 * nn2 + 348786722 * Power(nn2, 2))) + (-1 + nn2) * (906884951 + nn2 * (-1953245117 + 2 * nn2 * (1494081635 + 2 * nn2 * (-581376993 + 197672125 * nn2)))) + nn1 * (628131890 + nn2 * (-2239002083 + nn2 * (4826198781 + nn2 * (-3256066425 + 837246028 * nn2))))) * dpsub(nn1, -1 + nn2)) / (nn2 * (69836292 + Power(nn1, 4) * (700581974 + 299418033 * nn2) + Power(nn1, 3) * (808147573 + 9 * nn2 * (65244076 + 67183973 * nn2)) + Power(nn1, 2) * (741319811 + nn2 * (409794793 + nn2 * (662852667 + 186032743 * nn2))) + nn2 * (150917228 + nn2 * (744525710 + nn2 * (569540242 + 7 * nn2 * (96356007 + 112955500 * nn2)))) + nn1 * (889623247 + nn2 * (145097537 + nn2 * (663050036 + nn2 * (883606187 + 418623014 * nn2))))))); } // 0 残りは対称性を利用して埋める. repi(i, n / 2 + 1, n) dp[i] = dp[n - i]; //dump(dp); mint res = 0; repi(i, m, n) res += dp[i]; EXIT(res); }