結果
問題 | No.723 2つの数の和 |
ユーザー | yuppe19 😺 |
提出日時 | 2018-08-06 16:11:13 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 73 ms / 2,000 ms |
コード長 | 3,358 bytes |
コンパイル時間 | 955 ms |
コンパイル使用メモリ | 90,532 KB |
実行使用メモリ | 12,392 KB |
最終ジャッジ日時 | 2024-09-19 18:13:01 |
合計ジャッジ時間 | 3,394 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 61 ms
12,388 KB |
testcase_01 | AC | 65 ms
12,256 KB |
testcase_02 | AC | 64 ms
12,260 KB |
testcase_03 | AC | 69 ms
12,264 KB |
testcase_04 | AC | 69 ms
12,392 KB |
testcase_05 | AC | 71 ms
12,388 KB |
testcase_06 | AC | 71 ms
12,388 KB |
testcase_07 | AC | 66 ms
12,388 KB |
testcase_08 | AC | 70 ms
12,388 KB |
testcase_09 | AC | 71 ms
12,388 KB |
testcase_10 | AC | 66 ms
12,392 KB |
testcase_11 | AC | 65 ms
12,260 KB |
testcase_12 | AC | 67 ms
12,388 KB |
testcase_13 | AC | 72 ms
12,264 KB |
testcase_14 | AC | 63 ms
12,384 KB |
testcase_15 | AC | 68 ms
12,388 KB |
testcase_16 | AC | 68 ms
12,264 KB |
testcase_17 | AC | 71 ms
12,384 KB |
testcase_18 | AC | 70 ms
12,392 KB |
testcase_19 | AC | 71 ms
12,384 KB |
testcase_20 | AC | 62 ms
12,388 KB |
testcase_21 | AC | 62 ms
12,264 KB |
testcase_22 | AC | 65 ms
12,384 KB |
testcase_23 | AC | 73 ms
12,388 KB |
testcase_24 | AC | 67 ms
12,388 KB |
ソースコード
#include <cmath> #include <iostream> #include <tuple> #include <vector> using namespace std; using i64 = long long; // {{{ mod_mul, extgcd, mod_inv, mod_pow inline i64 mod_mul(const i64& x, const i64& y, const i64& m) { // yとmの最大ビット長はともに48ビット。 // http://codeforces.com/blog/entry/15884 // 12 < floor(63 - log2(MAX_VALUE)) = 15 // 0xfff = (1<<12) - 1 i64 b, res = y * (x & 0xfff); res += (b=(y<<12) % m) * ((x>>12) & 0xfff); res += (b=(b<<12) % m) * ((x>>24) & 0xfff); res += (b<<12) % m * ((x>>36) & 0xfff); res %= m; return res; } inline tuple<i64, i64, i64> extgcd(const i64& x, const i64& y) { if(y == 0) { return {1LL, 0LL, x}; } i64 a, b, d; tie(a, b, d) = extgcd(y, x%y); return {b, a-x/y*b, d}; } inline i64 mod_inv(const i64& a, const i64& m) { i64 x, _, d; tie(x, _, d) = extgcd(a, m); return (x % m + m) % m; } inline i64 mod_pow(const i64& a, const i64& r, const i64& n, const i64& m) { if(n == 0) { return r; } if(n & 1) { return mod_pow(a, mod_mul(a, r, m), n-1, m); } return mod_pow(mod_mul(a, a, m), r, n>>1, m); } inline i64 mod_pow(const i64 a, const i64 n, const i64 m) { return mod_pow(a, 1, n, m); } // }}} struct FMT { static vector<i64> convol (const vector<i64>& a, const vector<i64>& b); static void convol2(vector<i64>& a, vector<i64>& b); // a に答えが入る。メモリ節約が目的。fftmulで使用。 private: static constexpr i64 N = 5LL << 37; static constexpr i64 O = 2003LL; static constexpr i64 M = N * 211 + 1; static void fmt(vector<i64>&); static void ifmt(vector<i64>&); static void myfmt(vector<i64>&, const bool); }; // {{{ FMT 実装 void FMT::myfmt(vector<i64> &a, const bool inv) { const int n = int(a.size()); for(int H=1, W=n>>1; H<n; H<<=1, W>>=1) { vector<i64> y = a; i64 r = mod_pow(O, N/(H*2), M); if(inv) { r = mod_inv(r, M); } i64 w = 1; for(int k=0; k<H; ++k) { for(int j=0; j<W; ++j) { i64 y0 = y[2*W*k+j], y1 = mod_mul(y[2*W*k+j+W], w, M); a[W* k +j] = y0 + y1 < M ? y0 + y1 : y0 + y1 - M; a[W*(k+H)+j] = y0 < y1 ? y0 - y1 + M : y0 - y1; } w = mod_mul(w, r, M); } } } void FMT::fmt(vector<i64> &a) { myfmt(a, false); } void FMT::ifmt(vector<i64> &a) { myfmt(a, true); const int n = int(a.size()); i64 inv = mod_inv(n, M); for(int i=0; i<n; ++i) { a[i] = mod_mul(a[i], inv, M); } } vector<i64> FMT::convol(const vector<i64> &a, const vector<i64> &b) { int n = 1; while(n <= a.size() + b.size()) { n <<= 1; } vector<i64> ta = a, tb = b, c(n); ta.resize(n); tb.resize(n); fmt(ta); fmt(tb); for(int i=0; i<n; ++i) { c[i] = mod_mul(ta[i], tb[i], M); } ifmt(c); return c; } void FMT::convol2(vector<i64> &a, vector<i64> &b) { int n = 1; while(n <= a.size() + b.size()) { n <<= 1; } a.resize(n); b.resize(n); fmt(a); fmt(b); for(int i=0; i<n; ++i) { a[i] = mod_mul(a[i], b[i], M); } ifmt(a); } // }}} constexpr int N = int(powl(10, 5)) + 10; int main(void) { int n; i64 x; scanf("%d%lld", &n, &x); vector<i64> a(N); for(int i=0; i<n; ++i) { int v; scanf("%d", &v); ++a[v]; } vector<i64> c = FMT::convol(a, a); i64 res = 0; if(x < c.size()) { res = c[x]; } printf("%lld\n", res); return 0; }