Submission #1124040

#TimeUsernameProblemLanguageResultExecution timeMemory
1124040crimson231Random signals (kriii2_R)C++17
4 / 4
2439 ms4456 KiB
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <cassert> #include <vector> typedef long long ll; typedef long double ld; //typedef double ld; typedef std::vector<int> Vint; typedef std::vector<ld> Vld; const ld INF = 1e17; const ld TOL = 1e-10; const ld PI = acos(-1); const int LEN = 25; inline int sign(const ld& x) { return x < -TOL ? -1 : x > TOL; } inline bool zero(const ld& x) { return !sign(x); } inline bool eq(const ld& x, const ld& y) { return zero(x - y); } inline ll sq(const ll& x) { return x * x; } inline ld sq(const ld& x) { return x * x; } inline ld norm(ld th) { while (th < 0) th += 2 * PI; while (sign(th - 2 * PI) >= 0) th -= 2 * PI; return th; } int N, T, Q; struct Pos { ld x, y; Pos(ld X = 0, ld Y = 0) : x(X), y(Y) {} bool operator == (const Pos& p) const { return zero(x - p.x) && zero(y - p.y); } //bool operator != (const Pos& p) const { return !zero(x - p.x) || !zero(y - p.y); } bool operator < (const Pos& p) const { return zero(x - p.x) ? y < p.y : x < p.x; } Pos operator + (const Pos& p) const { return { x + p.x, y + p.y }; } Pos operator - (const Pos& p) const { return { x - p.x, y - p.y }; } Pos operator * (const ld& n) const { return { x * n, y * n }; } Pos operator / (const ld& n) const { return { x / n, y / n }; } ld operator * (const Pos& p) const { return x * p.x + y * p.y; } ld operator / (const Pos& p) const { return x * p.y - y * p.x; } Pos rot(const ld& the) const { return { x * cos(the) - y * sin(the), x * sin(the) + y * cos(the) }; } ld Euc() const { return x * x + y * y; } ld mag() const { return sqrt(Euc()); } //Pos unit() const { return *this / mag(); } ld rad() const { return atan2(y, x); } friend ld rad(const Pos& p1, const Pos& p2) { return atan2l(p1 / p2, p1 * p2); } friend std::istream& operator >> (std::istream& is, Pos& p) { is >> p.x >> p.y; return is; } friend std::ostream& operator << (std::ostream& os, const Pos& p) { os << p.x << " " << p.y; return os; } }; const Pos O = { 0, 0 }; typedef std::vector<Pos> Polygon; ld cross(const Pos& d1, const Pos& d2, const Pos& d3) { return (d2 - d1) / (d3 - d2); } ld cross(const Pos& d1, const Pos& d2, const Pos& d3, const Pos& d4) { return (d2 - d1) / (d4 - d3); } struct Circle { Pos c; int r; Circle(Pos c_ = Pos(), int r_ = 0) : c(c_), r(r_) {} bool operator == (const Circle& q) const { return c == q.c && r == q.r; } bool operator != (const Circle& q) const { return !(q == *this); } bool operator < (const Circle& q) const { return c == q.c ? r < q.r : c < q.c; } bool operator < (const Pos& p) const { return sign(r - (c - p).mag()) < 0; } bool operator >= (const Pos& p) const { return sign(r - (c - p).mag()) >= 0; } bool outside(const Circle& q) const { return sign((c - q.c).Euc() - sq((ll)r + q.r)) >= 0; } Pos p(const ld& t) const { return c + Pos(r, 0).rot(t); } ld rad(const Pos& p) const { return (p - c).rad(); } ld area(const ld& lo, const ld& hi) const { return (hi - lo) * r * r * .5; } ld green(const ld& lo, const ld& hi) const { Pos s = Pos(cos(lo), sin(lo)), e = Pos(cos(hi), sin(hi)); ld fan = area(lo, hi); Pos m = c + (s + e) * r * (ld).5; ld tz = (cos(lo) - cos(hi)) * m.y * r; return fan + tz - (s / e) * r * r * (ld).5; } inline friend std::istream& operator >> (std::istream& is, Circle& c) { is >> c.c >> c.r; return is; } inline friend std::ostream& operator << (std::ostream& os, const Circle& c) { os << c.c << " " << c.r; return os; } }; Vld intersections(const Circle& a, const Circle& b) { Pos ca = a.c, cb = b.c; Pos vec = cb - ca; ll ra = a.r, rb = b.r; ld distance = vec.mag(); ld rd = vec.rad(); if (vec.Euc() > sq(ra + rb) + TOL) return {}; if (vec.Euc() < sq(ra - rb) - TOL) return {}; ld X = (ra * ra - rb * rb + vec.Euc()) / (2 * distance * ra); if (X < -1) X = -1; if (X > 1) X = 1; ld h = acos(X); Vld ret = {}; ret.push_back(norm(rd - h)); if (zero(h)) return ret; ret.push_back(norm(rd + h)); return ret; } //struct Arc { // ld lo, hi; // Arc(ld l_ = 0, ld h_ = 0) : lo(l_), hi(h_) {} // bool operator < (const Arc& a) const { return zero(lo - a.lo) ? hi < a.hi : lo < a.lo; } // inline friend std::istream& operator >> (std::istream& is, Arc& a) { is >> a.lo >> a.hi; return is; } // inline friend std::ostream& operator << (std::ostream& os, const Arc& a) { os << a.lo << " " << a.hi; return os; } //}; //typedef std::vector<Arc> Arcs; struct Station { int x, y; int M, L, U; int r[20], s[20], w[20]; Vld A[20]; bool F[20]; Station(int x0 = 0, int y0 = 0, int m0 = 0, int l0 = 0, int u0 = 0) : x(x0), y(y0), M(m0), L(l0), U(u0) { for (int i = 0; i < 20; i++) r[i] = 0, s[i] = 0, w[i] = 0, F[i] = 0, A[i].clear(); } Pos p() const { return Pos(x, y); } Circle c(const int& i) const { return Circle(p(), r[i]); } } S[LEN]; struct Pow { int s, w; Pow(int s_ = 0, int w_ = 0) : s(s_), w(w_) {} bool operator < (const Pow& p) const { return s == p.s ? w > p.w : s > p.s; } }; struct Prob { ld p; int i, s; bool operator < (const Prob& o) const { return s > o.s; } }; //ld prob[LEN]; //ld expect(const int& i, const int& j, const Pos& mid) { // int sz; // std::vector<Prob> P, M; // Prob p, m; // for (int k = 0; k < N; k++) { // prob[k] = 1; // int all = S[k].U - S[k].L + 1; // int L = S[k].L; // int U = S[k].U; // std::vector<Pow> PW; // for (int l = 0; l < S[k].M; l++) { // if (IN[i][j]) PW.push_back(Pow(S[k].s[l], S[k].w[l])); // } // std::sort(PW.begin(), PW.end()); // sz = PW.size(); // for (int j = 0; j < sz; j++) { // int s = PW[j].s; // int w = PW[j].w; // if (w < L) w = L; // int diff = U - w + 1; // if (diff > 0) { // U = w - 1; // p.p = (ld)diff / all; // p.i = i; // p.s = s; // P.push_back(p); // } // } // } // std::sort(P.begin(), P.end()); // ld per = 1.; // ld total = 0; // sz = P.size(); // for (int i = 0; i < sz; i++) { // p = P[i]; // total += p.s * per * p.p / prob[p.i]; // per = per / prob[p.i]; // prob[p.i] -= p.p; // per = per * prob[p.i]; // } // return total; //} ld POS[LEN], NEG[LEN]; ld expect(const int& i, const int& j, const Pos& mid) { int sz; std::vector<Prob> P, M; Prob p, m; Circle cij = S[i].c(j); for (int k = 0; k < N; k++) { POS[k] = 1; NEG[k] = 1; int all = S[k].U - S[k].L + 1; int pl = S[k].L; int pu = S[k].U; int nl = S[k].L; int nu = S[k].U; std::vector<Pow> PP, MM; for (int l = 0; l < S[k].M; l++) { Circle ckl = S[k].c(l); if (ckl >= mid) PP.push_back(Pow(S[k].s[l], S[k].w[l])); if (ckl == cij) continue; if (ckl >= mid) MM.push_back(Pow(S[k].s[l], S[k].w[l])); } std::sort(PP.begin(), PP.end()); sz = PP.size(); for (int l = 0; l < sz; l++) { int s = PP[l].s; int w = PP[l].w; if (w < pl) w = pl; int diff = pu - w + 1; if (diff > 0) { pu = w - 1; p.p = (ld)diff / all; p.i = k; p.s = s; P.push_back(p); } } std::sort(MM.begin(), MM.end()); sz = MM.size(); for (int l = 0; l < sz; l++) { int s = MM[l].s; int w = MM[l].w; if (w < nl) w = nl; int diff = nu - w + 1; if (diff > 0) { nu = w - 1; m.p = (ld)diff / all; m.i = k; m.s = s; M.push_back(m); } } } ld total = 0, per; per = 1.; std::sort(P.begin(), P.end()); sz = P.size(); //assert(sz); for (int k = 0; k < sz; k++) { p = P[k]; total += p.s * per * p.p / POS[p.i]; per = per / POS[p.i]; POS[p.i] -= p.p; per = per * POS[p.i]; } if (M.size()) { per = 1.; std::sort(M.begin(), M.end()); sz = M.size(); for (int k = 0; k < sz; k++) { m = M[k]; total -= m.s * per * m.p / NEG[m.i]; per = per / NEG[m.i]; NEG[m.i] -= m.p; per = per * NEG[m.i]; } } return total; } void solve() { std::cin.tie(0)->sync_with_stdio(0); std::cout.tie(0); std::cout << std::fixed; std::cout.precision(15); ld A = 0; std::cin >> N; for (int i = 0; i < N; i++) { std::cin >> S[i].x >> S[i].y >> S[i].M >> S[i].L >> S[i].U; for (int j = 0; j < S[i].M; j++) std::cin >> S[i].r[j] >> S[i].s[j] >> S[i].w[j]; for (int j = 0; j < S[i].M; j++) { for (int k = j + 1; k < S[i].M; k++) { if (S[i].c(j) == S[i].c(k)) S[i].F[k] = 1; } } } for (int i = 0; i < N; i++) { for (int j = 0; j < S[i].M; j++) { Vld& V = S[i].A[j]; V = { 0 }; Circle cij = S[i].c(j); for (int k = 0; k < N; k++) { if (k == i) continue; for (int l = 0; l < S[k].M; l++) { Circle ckl = S[k].c(l); if (i < k && cij == ckl) S[k].F[l] = 1; ll d1 = sq((ll)S[i].x - S[k].x) + sq((ll)S[i].y - S[k].y); if (!d1) continue; ll d2 = sq((ll)S[i].r[j] + S[k].r[l]); ll d3 = sq((ll)S[i].r[j] - S[k].r[l]); if (d1 > d2 || d1 < d3) continue; Vld inxs = intersections(cij, ckl); for (const ld& x : inxs) V.push_back(x); } } std::sort(V.begin(), V.end()); V.erase(unique(V.begin(), V.end(), eq), V.end()); V.push_back(PI * 2); } } for (int i = 0; i < N; i++) { for (int j = 0; j < S[i].M; j++) { if (S[i].F[j]) continue; Circle cij = S[i].c(j); const Vld& V = S[i].A[j]; int sz = V.size(); for (int k = 0; k < sz - 1; k++) { const ld& s = V[k], e = V[k + 1]; if (eq(s, e)) continue; ld a = cij.green(s, e); ld m = (s + e) * .5; Pos mid = cij.p(m); A += expect(i, j, mid) * a; } } } std::cout << A << "\n"; return; } int main() { solve(); return 0; }//boj10910 hint from kcm1700
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...