Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- using ll = long long;
- #define pb emplace_back
- #define int ll
- const int maxn = 82;
- const ll inf = 1ll << 55;
- int n, m;
- int x[maxn], y[maxn];
- double dp[maxn][maxn];
- ll sq(ll v) { return v * v; }
- int h[maxn];
- ll u, d, b;
- void make(int x1, int y1, int x2, int y2) {
- u = y1-y2;
- d = x1-x2;
- if (d < 0) d = -d, u = -u;
- b = y1 * d - x1 * u;
- }
- int F(ll x) {
- ll val = x * u + b, res = val / d;
- return (res * d == val ? res : res+1);
- }
- pair<ll,ll> FD(ll x) {
- return {x * u + b, d};
- }
- bool fok(int x1, int y1, int x2, int y2) {
- if (x1 > x2) swap(x1, x2), swap(y1, y2);
- {
- bool same;
- int a = lower_bound(x, x+n, x1)-x, b = lower_bound(x, x+n, x2)-x;
- same = a == b;
- if (a == b && ((a&1) || (x[a] == x1 && x1 == x2))) {
- return true;
- }
- a = lower_bound(y, y+n, y1)-y, b = lower_bound(y, y+n, y2)-y;
- if (a == b && ((a&1) || (y[a] == y1 && y1 == y2)) ){
- return true;
- }
- if (same && a == b) {
- return true;
- }
- if (same ^ (a==b))
- return false;
- }
- make(x1, y1, x2, y2);
- for (int i = 0;i < n;++i) {
- if (x[i] < x1 || (x[i] == x1 && (~i&1))) continue;
- if (x[i] >= x2 && (i&1)) break;
- int val = F(x[i]);
- int p = lower_bound(y, y+n, val) - y;
- if (y[p] * d == (u * x[i] + b)) {
- if (y1 < y2 && ((~p&1) ^ (i&1))) return false;
- if (y1 > y2 && ( p&1) ^ (i&1)) return false;
- }
- else {
- if ((~p) & 1) return false;
- auto [u, d] = FD(min(x[i+1], x2));
- if (y1 < y2 && (i&1) && u > d * y[p]) return false;
- if (y1 > y2 && (i&1) && u < d * y[p-1]) return false;
- }
- }
- return true;
- }
- #define ok fok
- double solve(int x1, int y1, int x2, int y2) {
- if (fok(x1, y1, x2, y2))
- return sqrt(sq(x1-x2) + sq(y1-y2));
- for (int i = 0;i < maxn;++i)
- for (int j = 0;j < maxn;++j)
- dp[i][j] = inf;
- double res = inf;
- int hr = 0;
- while (x[hr+1] <= x1) ++hr;
- for (int i = hr;i < m-2;++i) {
- for (int j = 0;j < n-2;++j) {
- if (ok(x1, y1, x[i], y[j])) {
- dp[i][j] = sqrt(sq(x1-x[i]) + sq(y1-y[j]));
- }
- }
- }
- int cnt = 0;
- for (int i = hr;i < m;++i) {
- if (x[i] > x2 && ++cnt == 2) break;
- for (int j = 0;j < n-2;++j) {
- for (int k = 0;k < n-2;++k)
- dp[i][k] = min(dp[i][k], dp[i][j] + abs(y[k]-y[j]));
- for (int k = i+1;k < m-2;++k) {
- for (int l = 0;l < n-2;++l)
- if (ok(x[i], y[j], x[k], y[l])) {
- dp[k][l] = min(dp[k][l], dp[i][j] + sqrt(sq(x[k]-x[i]) + sq(y[l]-y[j])));
- }
- }
- if (fok(x[i], y[j], x2, y2)) {
- res = min(res, dp[i][j] + sqrt(sq(x2-x[i]) + sq(y2-y[j])));
- }
- }
- }
- return res;
- }
- signed main() {
- ios_base::sync_with_stdio(0), cin.tie(0);
- cout << fixed << setprecision(15);
- cin >> n >> m;
- n <<= 1, m <<= 1;
- for (int i = 0;i < n;++i)
- cin >> y[i];
- for (int i = 0;i < m;++i)
- cin >> x[i];
- y[n++] = 200000;
- y[n++] = 200001;
- x[m++] = 200000;
- x[m++] = 200001;
- int q;
- cin >> q;
- while (q--) {
- int x1, x2, y1, y2;
- cin >> x1 >> y1 >> x2 >> y2;
- if (x1 > x2)
- swap(x1, x2), swap(y1, y2);
- cout << solve(x1, y1, x2, y2) << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment