QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#820448 | #4601. Vale of Eternal | SGColin | AC ✓ | 44ms | 6568kb | C++20 | 10.2kb | 2024-12-18 21:28:40 | 2024-12-18 21:28:40 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define pii pair<int, int>
#define rep(i, x, y) for (int i = (x); i <= (y); ++i)
#define per(i, x, y) for (int i = (x); i >= (y); --i)
inline ll rd() {
ll x = 0;
bool f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= (c == '-');
for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return f ? -x : x;
}
typedef long long T;
#define let const auto
#define lett const T
#define letp const P // P for point
#define lets const S // S for segment
#define letl const L // L for line
#define letc const C // C for convex
#define z(x) (abs((x)) <= eps) // is zero
const T eps = 1e-8;
constexpr double PI=3.1415926535897932384;
struct P {
T x, y;
P (T x = 0, T y = 0) : x(x), y(y) {}
P operator + (letp &p) const {return {x + p.x, y + p.y};}
P operator - (letp &p) const {return {x - p.x, y - p.y};}
P operator * (lett &d) const {return {x * d, y * d};}
P operator / (lett &d) const {return {x / d, y / d};}
P operator - () const {return {-x, -y};}
T operator | (letp &p) const {return x * p.x + y * p.y;} // dot
T operator ^ (letp &p) const {return x * p.y - y * p.x;} // cross
// P rot(double ang) const { // counterclockwise rotation (ang) angle
// double cosa = cos(ang), sina = sin(ang);
// return {x * cosa - y * sina, x * sina + y * cosa};
// }
bool operator == (letp &p) const {return z(x - p.x) && z(y - p.y);}
bool operator != (letp &p) const {return ! operator == (p);}
bool operator < (letp &p) const {return z(x - p.x) ? y < p.y : x < p.x;}
bool operator > (letp &p) const {return !(*this < p || *this == p);}
// left(counterclockwise) = 1 | on = 0 | right(clockwise) = -1
int ori(letp &p) const {T t = (*this) ^ p; return (t > eps) - (t < -eps);}
T norm() const {return x * x + y * y;}
P proj (letp &p) const {return (*this) * (((*this) | p) / norm());}
P refl (letp &p) const {return proj(p) * 2 - p;}
void print() const {printf("%lld %lld\n", x, y);}
} zero;
double abs(letp &p) {return sqrt(p.norm());}
P normalize(letp &p) {return p / abs(p);}
P perp(letp &p) {return {-p.y, p.x};} // turn pi / 2 left
P perpr(letp &p) {return {p.y, -p.x};} // turn pi / 2 right
bool orth(letp &p, letp &q) {return (p | q) == 0;}
bool para(letp &p, letp &q) {return (p ^ q) == 0;}
struct argcmp { // compared by polar angle
bool operator() (letp &a, letp &b) const {
const auto quad = [](letp &a) {
if (a.y < -eps) return 1; // halfplane with negative y
if (a.y > eps) return 4; // halfplane with positive y
if (a.x < -eps) return 5; // negative x-axis
if (a.x > eps) return 3; // positive x-axis
return 2; // origin
};
const int qa = quad(a), qb = quad(b);
if (qa != qb) return qa < qb;
const auto t = a ^ b; //in the same quad
// sorted by length in increasing order when parallel
// if (z(t)) return norm(a) < norm(b) - eps;
return t > eps;
}
};
struct L {
P p, v;
int ori (letp &a) const {return v.ori(a - p);}
P inter(letl &l) const {return p + v * ((l.v ^ (p - l.p)) / (v ^ l.v));}
L shift(letp &d) const {return {p + d, v};}
L shiftl(double d) const {return {p + perp(v) * d / abs(v), v};}
double dis(letp &a) const {return abs(v ^ (a - p)) / abs(v);}
};
struct S {
P a, b;
// on endpoints = -1 | out = 0 | in = 1
int is_on(letp &p) const {
if (p == a || p == b) return -1;
return (p - a).ori(p - b) == 0 && ((p - a) | (p - b)) < -eps;
}
// inter on endpoints = -1 | not inter = 0 | inter inside = 1
int is_inter(letl &l) const {
if (l.ori(a) == 0 || l.ori(b) == 0) return -1;
return l.ori(a) != l.ori(b);
}
// inter on endpoints = -1 | not inter = 0 | inter inside = 1
int is_inter(lets &s) const {
if (is_on(s.a) || is_on(s.b) || s.is_on(a) || s.is_on(b)) return -1;
letl &l{a, b - a}, ls{s.a, s.b - s.a};
return l.ori(s.a) * l.ori(s.b) == -1 && ls.ori(a) * ls.ori(b) == -1;
}
double dis(letp &p) const {
if (((p - a) | (b - a)) < -eps || ((p - b) | (a - b)) < -eps)
return min(abs(a - p), abs(b - p));
return L{a, b - a}.dis(p);
}
};
struct Polygon {
vector<P> p; // counterclockwise
Polygon(const vector<P> p = {}) : p(p) {}
size_t nxt(const size_t i) const {return i == p.size() - 1 ? 0 : i + 1;}
size_t pre(const size_t i) const {return i == 0 ? p.size() - 1 : i - 1;}
T double_area() const {
T sum = 0;
for (size_t i = 0; i < p.size(); ++i) sum += (p[i] ^ p[nxt(i)]);
return sum;
}
double area() const {return double_area() / 2.0;}
double circ() const {
long double sum = 0;
for (size_t i = 0; i < p.size(); ++i) sum += abs(p[i] - p[nxt(i)]);
return sum;
}
// pair<is_on_edge, winding number> , out = [winding number = 0]
pair<bool,int> winding(letp &a) const {
int cnt = 0;
for (size_t i = 0; i < p.size(); ++i) {
letp u = p[i], v = p[nxt(i)];
if (z((a - u) ^ (a - v)) && ((a - u) | (a - v)) <= eps) return {true, 0};
if (z(u.y - v.y)) continue;
letl uv{u, v - u};
if (u.y < v.y - eps && uv.ori(a) <= 0) continue;
if (u.y > v.y + eps && uv.ori(a) >= 0) continue;
if (u.y < a.y - eps && v.y >= a.y - eps) cnt++;
if (u.y >= a.y - eps && v.y < a.y - eps) cnt--;
}
return {false, cnt};
}
};
struct C : Polygon {
C (const vector<P> &p = {}) : Polygon(p) {}
C operator + (letc &c) const {
const auto &p = this -> p;
vector<S> e1(p.size()), e2(c.p.size());
vector<S> edge(p.size() + c.p.size());
vector<P> res; res.reserve(p.size() + c.p.size());
const auto cmp = [](lets &u, lets &v) {
return argcmp()(u.b - u.a, v.b - v.a);
};
for (size_t i = 0; i < p.size(); ++i) e1[i] = {p[i], p[this -> nxt(i)]};
for (size_t i = 0; i < c.p.size(); ++i) e2[i] = {c.p[i], c.p[c.nxt(i)]};
rotate(e1.begin(), min_element(e1.begin(), e1.end(), cmp), e1.end());
rotate(e2.begin(), min_element(e2.begin(), e2.end(), cmp), e2.end());
merge(e1.begin(), e1.end(), e2.begin(), e2.end(), edge.begin(), cmp);
const auto check = [](const vector<P> &res, letp &u) {
const auto b1 = res.back(), b2 = *prev(res.end(), 2);
return (b1 - b2).ori(u - b1) == 0 && ((b1 - b2) | (u - b1)) >= -eps;
};
auto u = e1[0].a + e2[0].a;
for (const auto &v : edge) {
while (res.size() > 1 && check(res, u)) res.pop_back();
res.push_back(u); u = u + v.b - v.a;
}
if (res.size() > 1 && check(res, res[0])) res.pop_back();
return {res};
}
// O(log n) : on = -1 | out = 0 | in = 1
int is_in(letp &a) const {
const auto &p = this -> p;
if (p.size() == 1) return a == p[0] ? -1 : 0;
if (p.size() == 2) return S{p[0], p[1]}.is_on(a) ? -1 : 0;
if (a == p[0]) return -1;
if ((p[1] - p[0]).ori(a - p[0]) == -1) return 0;
if ((p.back() - p[0]).ori(a - p[0]) == 1) return 0;
let cmp = [&](letp &u, letp &v) {return (u - p[0]).ori(v - p[0]) == 1;};
const size_t i = lower_bound(p.begin() + 1, p.end(), a, cmp) - p.begin();
if (i == 1) return S{p[0], p[i]}.is_on(a) ? -1 : 0;
if (i == p.size() - 1 && S{p[0], p[i]}.is_on(a)) return -1;
if (S{p[i - 1], p[i]}.is_on(a)) return -1;
return (p[i] - p[i - 1]).ori(a - p[i - 1]) > 0;
}
template<typename F> size_t extreme(const F &dir) const {
let &p = this -> p;
let check = [&](const size_t i) {return dir(p[i]).ori(p[nxt(i)] - p[i]) >= 0;};
let dir0 = dir(p[0]);
let check0 = check(0);
if (!check0 && check(p.size() - 1)) return 0;
const auto cmp = [&](letp &v) {
const size_t vi = &v - p.data();
if (vi == 0) return 1;
let checkv = check(vi);
let t = dir0.ori(v - p[0]);
if (vi == 1 && checkv == check0 && dir0.ori(v - p[0]) == 0) return 1;
return checkv ^ (checkv == check0 && t <= 0);
};
return partition_point(p.begin(), p.end(), cmp) - p.begin();
}
pair<size_t,size_t> tangent(letp &a) const {
const size_t i = extreme([&](letp &u){return u - a;});
const size_t j = extreme([&](letp &u){return a - u;});
return {i, j};
}
pair<size_t,size_t> tangent(letl &a) const {
const size_t i = extreme([&](...){return a.v;});
const size_t j = extreme([&](...){return -a.v;});
return {i, j};
}
};
C convexHull(vector<P> p) {
vector<P> st;
sort(p.begin(), p.end());
const auto check = [](const vector<P> &st, letp &u) {
const auto back1 = st.back(), back2 = *prev(st.end(), 2);
return (back1 - back2).ori(u - back2) <= 0;
};
for (letp &u : p) {
while (st.size() > 1 && check(st, u)) st.pop_back();
st.push_back(u);
}
size_t k=st.size();
p.pop_back(); reverse(p.begin(),p.end());
for (letp &u : p) {
while (st.size() > k && check(st, u)) st.pop_back();
st.push_back(u);
}
st.pop_back();
return {st};
}
C c;
vector<P> p;
inline void work() {
p.clear();
int n = rd(), q = rd(); p.resize(n);
for (int i = 0; i < n; ++i) {p[i].x = rd(); p[i].y = rd();}
c = convexHull(p);
ll s = c.double_area();
ll dlt = 0;
for (size_t i = 0; i < c.p.size(); ++i) {
P cur = c.p[c.nxt(i)] - c.p[i];
dlt += max(abs(cur.x), abs(cur.y));
}
for (int i = 1; i <= q; ++i) {
ll t = rd();
ll ans = s + 4 * t * t + 2 * t * dlt;
printf("%lld", ans / 2);
puts((ans & 1) ? ".5" : ".0");
}
}
int main() {
for (int t = rd(); t; --t) work();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 44ms
memory: 6568kb
input:
11 3 3 2 3 4 3 1 1 1 2 3 3 3 4 1 3 4 2 1 2 3 4 10 10 37 76 71 57 66 82 85 85 21 12 94 70 60 6 68 52 2 68 29 53 19 21 46 9 99 65 44 90 50 21 10 10 26 21 77 57 38 96 80 94 5 74 95 53 58 99 50 54 74 25 29 4 54 74 50 51 82 100 15 77 42 64 10 10 14 97 5 89 37 42 36 94 67 68 20 92 42 61 67 77 53 44 99 92 ...
output:
11.0 24.0 41.0 27.0 45.0 67.0 10297.0 10971.0 20746.0 7167.0 49737.0 29847.0 19872.0 44022.0 22542.0 10971.0 25391.0 35691.0 23523.0 23984.0 40259.0 51473.0 9908.0 37374.0 19979.0 30341.0 33215.5 41660.5 28085.5 33750.5 17010.5 4032.5 12239.5 22904.5 32684.5 29582.5 45013.5 5764.5 26279.5 9208.5 170...
result:
ok 203046 lines