結果
| 問題 |
No.695 square1001 and Permutation 4
|
| コンテスト | |
| ユーザー |
drken1215
|
| 提出日時 | 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;
}
drken1215