QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#375657#7862. Land TradedarksebaCompile Error//C++234.6kb2024-04-03 14:36:022024-04-03 14:36:02

Judging History

你现在查看的是最新测评结果

  • [2024-04-03 14:36:02]
  • 评测
  • [2024-04-03 14:36:02]
  • 提交

answer

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include <bits/stdc++.h>
using namespace std;
#define rep(a, b, c) for (int a = (b); a < (c); a++)
#define all(x) begin(x), end(x)
#define sz(x) int(size(x))
using vi = vector<int>;
using ll = long long;
using pii = pair<int, int>;

const double eps = 1e-9;

template<class T>
struct Point {
    using P = Point;
    T x, y;
    explicit Point(T x=0, T y=0): x(x), y(y) {}
    P operator+(P p) const { return P(x+p.x, y+p.y); }
    P operator-(P p) const { return P(x-p.x, y-p.y); }
    P operator*(T d) const { return P(x*d, y*d); }
    P operator/(T d) const { return P(x/d, y/d); }
    T dot(P p) const { return x*p.x + y*p.y; }
    T cross(P p) const { return x*p.y - y*p.x; }
    T cross(P a, P b) const { return (a-*this).cross(b-*this); }
};

template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
    auto d = (e1 - s1).cross(e2 - s2);
    if (d == 0)
        return {-(s1.cross(e1, s2) == 0), P(0, 0)};
    auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
    return {1, (s1 * p + e1 * q) / d};
}

typedef Point<double> P;
vector<P> polygonCut(const vector<P>& poly, P s, P e) {
    vector<P> res;
    rep (i, 0, sz(poly)) {
        P cur = poly[i], prev = i ? poly[i-1] : poly.back();
        bool side = s.cross(e, cur) < 0;
        if (side != (s.cross(e, prev) < 0))
            res.push_back(lineInter(s, e, cur, prev).second);
        if (side) res.push_back(cur);
    }
    return res;
}

template<class T>
T polygonArea2(vector<Point<T>>& v) {
    T a = v.back().cross(v[0]);
    rep (i, 0, sz(v) - 1) a += v[i].cross(v[i+1]);
    return a;
}

vector<pair<char, int>> stk;
int ptr = 0;
pair<char, int> pop() { return stk[ptr++]; }
pair<char, int> peek() { return stk[ptr]; }

map<tuple<int, int, int>, int> id;
vector<tuple<int, int, int>> lines;

const int GRPS = 301 * 301;
using bs = bitset<GRPS>;

vector<pair<vector<P>, vector<bool>>> polys;

bs parse() {
    auto [c, li] = pop();

    if (c == '(') {
        if (peek().first == '!') {
            pop();
            auto x = parse();
            assert(pop().first == ')');
            return ~x;
        }
        
        auto x = parse();
        auto op = pop().first;
        auto y = parse();
        assert(pop().first == ')');

        if (op == '&') return x & y;
        else if (op == '|') return x | y;
        else if (op == '^') return x ^ y;
        else assert(0);
    }
    
    assert(c == 0);
    bs x;
    rep (i, 0, sz(polys))
        x[i] = polys[i].second[li];
    
    return x;
}

void solve() {
    ll xlo, xhi, ylo, yhi;
    cin >> xlo >> xhi >> ylo >> yhi;

    string in;
    cin >> in;

    for (int i = 0; i < sz(in); ) {
        if (in[i] != '[') {
            stk.emplace_back(in[i++], 0);
            continue;
        }
        
        i++;

        int k = 0;
        while (in[i+k] != ',') k++;
        int a = stoi(in.substr(i, k));
        i += k + 1;

        k = 0;
        while (in[i+k] != ',') k++;
        int b = stoi(in.substr(i, k));
        i += k + 1;

        k = 0;
        while (in[i+k] != ']') k++;
        int c = stoi(in.substr(i, k));
        i += k + 1;

        int idx = sz(lines);
        lines.emplace_back(a, b, c);
        id[lines[idx]] = idx;
        stk.emplace_back(0, idx);
    }
    
    polys.push_back({{P(xlo, ylo), P(xhi, ylo), P(xhi, yhi), P(xlo, yhi)}, vector<bool>(sz(lines))});

    rep (i, 0, sz(lines)) {
        auto [a, b, c] = lines[i];

        vector<pair<vector<P>, vector<bool>>> nxt;
        P dir(b, -a), p0;

        if (a != 0) p0 = P(double(-c) / a);
        else p0 = P(0, double(-c) / b);

        auto p1 = p0 + dir;

        for (auto& [poly, sides] : polys) {
            auto res = polygonCut(poly, p0, p1);
            if (!res.empty()) {
                nxt.push_back({res, sides});
                nxt.back().second[i] = 0;
            }
            res = polygonCut(poly, p1, p0);
            if (!res.empty()) {
                nxt.push_back({res, sides});
                nxt.back().second[i] = 1;
            }
        }

        swap(polys, nxt);
    }

    auto res = parse();

    double ans = 0;
    rep (i, 0, sz(polys)) if (res[i]) 
        ans += polygonArea2(polys[i].first);

    ans /= 2;

    cout << setprecision(15) << fixed << ans << "\n";
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);

    // int t; cin >> t; while (t--)
    solve();

    return 0;
}

/*

-5 10 -10 5
((!([1,2,-3]&[10,3,-2]))^([-2,3,1]|[5,-2,7]))

*/

詳細信息

In file included from /usr/include/c++/13/string:43,
                 from /usr/include/c++/13/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:52,
                 from answer.code:4:
/usr/include/c++/13/bits/allocator.h: In destructor ‘constexpr std::__cxx11::basic_string<char>::_Alloc_hider::~_Alloc_hider()’:
/usr/include/c++/13/bits/allocator.h:184:7: error: inlining failed in call to ‘always_inline’ ‘constexpr std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = char]’: target specific option mismatch
  184 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/13/string:54:
/usr/include/c++/13/bits/basic_string.h:181:14: note: called from here
  181 |       struct _Alloc_hider : allocator_type // TODO check __is_final
      |              ^~~~~~~~~~~~