結果
| 問題 | No.206 数の積集合を求めるクエリ |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-17 15:14:24 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 274 ms / 7,000 ms |
| コード長 | 2,323 bytes |
| 記録 | |
| コンパイル時間 | 1,824 ms |
| コンパイル使用メモリ | 174,480 KB |
| 実行使用メモリ | 14,848 KB |
| 最終ジャッジ日時 | 2024-07-07 13:14:37 |
| 合計ジャッジ時間 | 6,827 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 28 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;
using ui64 = uint_fast64_t;
#define REP(i, n) for (i64 (i) = 0; (i) < (n); ++(i))
#define FOR(i, a, b) for (i64 (i) = (a); (i) < (b); ++(i))
namespace FastFourierTransform {
using C = complex< double >;
void DiscreteFourierTransform(vector<C> &F, bool rev) {
const int N = (int)F.size();
const double PI = (rev ? -1 : 1) * acos(-1);
for (int i = 0, j = 1; j + 1 < N; ++j) {
for (int k = N >> 1; k > (i ^= k); k >>= 1);
if (i > j) swap(F[i], F[j]);
}
C w, s, t;
for (int i = 1; i < N; i <<= 1) {
for (int k = 0; k < i; ++k) {
w = polar(1.0, PI / i * k);
for (int j = 0; j < N; j += i * 2) {
s = F[j + k];
t = C(
F[j + k + i].real() * w.real() - F[j + k + i].imag() * w.imag(),
F[j + k + i].real() * w.imag() + F[j + k + i].imag() * w.real()
);
F[j + k] = s + t, F[j + k + i] = s - t;
}
}
}
if (rev) for (int i = 0; i < N; ++i) F[i] /= N;
}
vector<long long> Multiply(const vector<int> &A, const vector<int> &B) {
int sz = 1;
while (sz < A.size() + B.size() - 1) sz <<= 1;
vector<C> F(sz), G(sz);
for (int i = 0; i < A.size(); ++i) F[i] = A[i];
for (int i = 0; i < B.size(); ++i) G[i] = B[i];
DiscreteFourierTransform(F, false);
DiscreteFourierTransform(G, false);
for (int i = 0; i < sz; ++i) F[i] *= G[i];
DiscreteFourierTransform(F, true);
vector<long long> X(A.size() + B.size() - 1);
for (int i = 0; i < A.size() + B.size() - 1; ++i) X[i] = F[i].real() + 0.5;
return (X);
}
};
int L, M, N, Q;
vector<int> A, B;
vector<int> inA, inB;
signed main() {
cin >> L >> M >> N;
inA.resize(N + 1);
inB.resize(N + 1);
A.resize(L);
REP(i, L) {
cin >> A[i];
inA[A[i]] = 1;
}
B.resize(M);
REP(i, M) {
cin >> B[i];
inB[N - B[i]] = 1;
}
auto C = FastFourierTransform::Multiply(inA, inB);
cin >> Q;
for (int i = 0; i < Q; ++i) {
cout << C[N + i] << endl;
}
}