結果
問題 | No.754 畳み込みの和 |
ユーザー | m1025o1184t |
提出日時 | 2019-12-20 05:26:13 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 312 ms / 5,000 ms |
コード長 | 2,715 bytes |
コンパイル時間 | 2,002 ms |
コンパイル使用メモリ | 182,204 KB |
実行使用メモリ | 11,296 KB |
最終ジャッジ日時 | 2024-07-07 13:50:34 |
合計ジャッジ時間 | 3,971 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 312 ms
11,168 KB |
testcase_01 | AC | 306 ms
11,296 KB |
testcase_02 | AC | 309 ms
11,168 KB |
ソースコード
#include <bits/stdc++.h> #define rep(i,n) for(int i=0;i<(n);++i) #define all(a) (a).begin(),(a).end() #define dunk(a) cout << (a) << endl using namespace std; typedef long long ll; template<int mod, int proot> struct NTT { vector<long long>pp, invpp;//memoize proot^(mod-1>>i) and inv long long power(long long a, int b) { long long ret = 1; while (b) { if (b & 1)ret = ret * a % mod; a = a * a % mod; b >>= 1; } return ret; } void dft(vector<int>& A, bool sign, int id) { if (id == 0)return; int N = 1 << id - 1; vector<int>F(N), G(N); for (int i = 0; i < N; i++) { F[i] = A[i << 1]; G[i] = A[i << 1 | 1]; } dft(F, sign, id - 1); dft(G, sign, id - 1); long long z = (sign ? invpp : pp)[id], p = 1; for (int i = 0; i < N; i++) { A[i] = (F[i] + p * G[i]) % mod; A[i + N] = (F[i] - p * G[i]) % mod; if (A[i + N] < 0)A[i + N] += mod; (p *= z) %= mod; } } vector<int>multiply(vector<int>A, vector<int>B) { if (A.empty() || B.empty()) { return(vector<int>){}; } int N = 1, sz = 0; vector<int>ret(A.size() + B.size() - 1); while (N < ret.size())N <<= 1, sz += 1; pp.resize(sz + 1); invpp.resize(sz + 1); pp[sz] = power(proot, mod - 1 >> sz); invpp[sz] = power(pp[sz], mod - 2); for (int i = sz - 1; i > 0; i -= 1) { pp[i] = pp[i + 1] * pp[i + 1] % mod; invpp[i] = invpp[i + 1] * invpp[i + 1] % mod; } A.resize(N); B.resize(N); dft(A, false, sz); dft(B, false, sz); for (int i = 0; i < N; i++)A[i] = (long long)A[i] * B[i] % mod; dft(A, true, sz); long long invN = power(N, mod - 2); for (int i = 0; i < ret.size(); i++)ret[i] = invN * A[i] % mod; return ret; } }; vector<int>multiply(vector<int>A, vector<int>B, const int mod) { for (int& a : A) { a %= mod; if (a < 0)a += mod; } for (int& b : B) { b %= mod; if (b < 0)b += mod; } vector<int>C1 = NTT<998244353, 3>().multiply(A, B); vector<int>C2 = NTT<469762049, 3>().multiply(A, B); vector<int>C3 = NTT<167772161, 3>().multiply(A, B); vector<int>C(C1.size()); for (int i = 0; i < C.size(); i++) { long long v1 = C1[i]; long long v2 = (C2[i] - v1) * 208783132 % 469762049; if (v2 < 0)v2 += 469762049; long long v3 = (C3[i] - v1 - v2 * 998244353) % 167772161 * 29562547 % 167772161; if (v3 < 0)v3 += 167772161; C[i] = (v1 + (v2 + v3 * 469762049) % mod * 998244353) % mod; } return C; } int main() { ios::sync_with_stdio(false); cin.tie(0); ll mod = 1000000007; int n; cin >> n; vector<int> a(n + 1), b(n + 1); rep(i, n + 1) { cin >> a[i]; } rep(i, n + 1) { cin >> b[i]; } vector<int> c = multiply(a, b, mod); ll ans = 0; rep(i, n + 1) { (ans += c[i]) %= mod; } dunk(ans); return 0; }