[BOJ] 1067 이동

이동

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <bits/stdc++.h>

#define ll long long
#define db double
#define cpd complex<double>
#define vcpd vector<cpd>
#define all(a) begin(a), end(a)
using namespace std;

db pi = acos(-1);
ll n;

vcpd fft(vcpd& a, int f) {
ll n = a.size();
vcpd ra(n);
for(ll k = 0; k < n; k++) {
ll b = 0;
for(ll z = 1; z < n; z *= 2) {
b *= 2;
if(k&z) b++;
}
ra[b] = a[k];
}
for(int m = 2; m <= n; m *= 2) {
cpd wm = exp(cpd{0,f*2*pi/m});
for(int k = 0; k < n; k+= m) {
cpd w = 1;
for(int j = 0; j < m/2; j++) {
cpd u = ra[k + j];
cpd t = w * ra[k + j + m / 2];
ra[k + j] = u + t;
ra[k + j + m / 2] = u - t;
w = w * wm;
}
}
}
if(f == -1)
for(int i = 0; i < n; i++) ra[i] /= n;

return ra;
}

void padding(vcpd& x) {
ll n = x.size(), lgn = log2(n);

if(pow(2,lgn) != n)
n = pow(2,lgn+1);

while(x.size() < n)
x.push_back(0);
}

ll solve(vcpd x, vcpd y) {
x.insert(end(x), all(x));
reverse(all(y));

padding(x);
padding(y);

y.resize(x.size());
auto tx = fft(x, 1), ty = fft(y, 1);

vcpd tp(x.size());

for(ll i = 0; i < x.size(); i++) tp[i] = tx[i] * ty[i];
auto p = fft(tp, -1);

ll res = 0;
for(auto& n : p)
res = max(res, (ll)round(n.real()));
return res;
}

int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin>>n;
vcpd x(n), y(n);

for(ll i = 0; i < n; i++) cin>>x[i];
for(ll i = 0; i < n; i++) cin>>y[i];
cout<<solve(x,y);

return 0;
}
Author: Song Hayoung
Link: https://songhayoung.github.io/2022/04/22/PS/BOJ/1067/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.