結果
問題 | No.695 square1001 and Permutation 4 |
ユーザー |
![]() |
提出日時 | 2018-06-29 02:54:53 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,551 ms / 7,000 ms |
コード長 | 1,789 bytes |
コンパイル時間 | 724 ms |
コンパイル使用メモリ | 73,592 KB |
実行使用メモリ | 42,496 KB |
最終ジャッジ日時 | 2024-07-22 19:34:22 |
合計ジャッジ時間 | 9,951 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 12 |
ソースコード
#include <iostream> #include <vector> using namespace std; inline long long mod(long long a, long long m) { return (a % m + m) % m; } // 拡張 Euclid の互除法 long long extGCD(long long a, long long b, long long &p, long long &q) { if (b == 0) { p = 1; q = 0; return a; } long long d = extGCD(b, a%b, q, p); q -= a/b * p; return d; } // 逆元 long long modinv(long long a, long long m) { long long x, y; extGCD(a, m, x, y); return mod(x, m); // 気持ち的には x % m だが、x が負かもしれないので } // 中国剰余定理 pair<long long, long long> ChineseRem(long long b1, long long m1, long long b2, long long m2) { long long p, q; long long d = extGCD(m1, m2, p, q); // p is inv of m1/d (mod. m2/d) if ((b2 - b1) % d != 0) return make_pair(0, -1); long long m = m1 * (m2/d); long long tmp = (b2 - b1) / d * p % (m2/d); long long r = mod(b1 + m1 * tmp, m); return make_pair(r, m); } int n, m; const int MOD[2] = {168647939, 592951213}; long long b[2]; vector<int> x; int dp[10000010]; int main() { cin >> n >> m; --n; x.resize(m); for (int i = 0; i < m; ++i) cin >> x[i]; for (int iter = 0; iter < 2; ++iter) { int p = MOD[iter]; dp[0] = 1; for (int i = 1; i <= (n+1)/2; ++i) { long long tmp = 0; for (auto xv : x) if (i >= xv) (tmp += dp[i - xv]) %= p; dp[i] = (int)tmp; } b[iter] = 0; for (int i = 0; i <= (n+1)/2; ++i) for (auto xv : x) { if (i + xv > (n+1)/2 && i + xv <= n) { (b[iter] += (long long)(dp[i]) * dp[n - (i + xv)]) %= p; } } } pair<long long, long long> res = ChineseRem(b[0], MOD[0], b[1], MOD[1]); cout << res.first << endl; }