QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#569175#9316. BoxesshiqiaqiayaCompile Error//C++176.3kb2024-09-16 21:08:482024-09-16 21:08:48

Judging History

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

  • [2024-09-16 21:08:48]
  • 评测
  • [2024-09-16 21:08:48]
  • 提交

answer

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>    // 包含 tree、gp_hash_table、cc_hash_table
#include <ext/pb_ds/priority_queue.hpp> // 引入后使用 STL 的堆需要 std::
#include <ext/rope>
using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;
template<class key, class val = null_type, class cmp = less<>>
using rb_tree = tree<key, val, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template<class key, class cmp = less<>>
using pairing_heap = __gnu_pbds::priority_queue<key, cmp>;
typedef long long ll;
#define int long long
#define debug(...) (cerr << #__VA_ARGS__ << " = ", ((cerr << __VA_ARGS__ << ", "), ...), cerr << "\n")
mt19937_64 rd(time(0));

template <class type>
struct point : array<type, 3> {
    using p = array<type, 3>;
    type operator / (const point & t) const { return p::at(0) * t[0] + p::at(1) * t[1] + p::at(2) * t[2]; }
    point operator * (const point & t) const { return {p::at(1) * t[2] - p::at(2) * t[1], p::at(2) * t[0] - p::at(0) * t[2], p::at(0) * t[1] - p::at(1) * t[0]}; }
    point operator + (const point & t) const { return point(*this) += t; }
    point operator - (const point & t) const { return point(*this) -= t; }
    point operator * (const type & t) const { return point(*this) *= t; }
    point operator / (const type & t) const { return point(*this) /= t; }
    point & operator += (const point & t) { return *this = {p::at(0) + t[0], p::at(1) + t[1], p::at(2) + t[2]}; }
    point & operator -= (const point & t) { return *this = {p::at(0) - t[0], p::at(1) - t[1], p::at(2) - t[2]}; }
    point & operator *= (const type & t) { return *this = {p::at(0) * t, p::at(1) * t, p::at(2) * t}; }
    point & operator /= (const type & t) { return *this = {p::at(0) / t, p::at(1) / t, p::at(2) / t}; }
    type sqrlen() const { return *this / *this; }
    type len() const { return sqrt(sqrlen()); }

    void shake(type eps = 1e-12) {    // 微小扰动,去掉四点共面
        uniform_real_distribution<type> dist(-0.5, 0.5);
        for (auto & t : *this) {
            t += dist(rd) * eps;
        }
    }
 
    struct line : array<point, 2> {
        using p = array<point, 2>; // 0 -> 1
        point v() { return p::at(1) - p::at(0); }
        point pos(const point & t) { return v() * (t - p::at(0)); }  // sqrlen() == 0 在直线上
        point pos(const line & t) { return v() * t.v(); } // sqrlen() == 0 平行
        type dir(const line & t) { return v() / t.v(); }    // == 0 垂直,> 0 同向
        type dis_to_line(const point & t) { return pos(t).len() / v().len(); }
        bool equal(const line & t) { return dir(t) > 0 && pos(t[0]).sqrlen() == 0; }
        point intersect(const line & t) {  // 需要保证不平行,如果直线异面,返回的是俩直线的垂线在 *this 直线上的垂足
            return p::at(0) + v() * (t.pos(p::at(0)) / pos(t)) / pos(t).sqrlen();
        }
    };

    struct face : array<point, 3> {
        using p = array<point, 3>; // 从上方看逆时针 0 -> 1 - > 2
        point v() { return (p::at(1) - p::at(0)) * (p::at(2) - p::at(0)); }
        type pos(const point & t) { return v() / (t - p::at(0)); }   // > 0 严格在上方,== 0 在面上
        type pos(const line & t) { return v() / t.v(); }   // == 0 平行
        point pos(const face & t) { return v() * t.v(); } // sqrlen() == 0 平行
        point dir(const line & t) { return v() * t.v(); }   // sqrlen() == 0 垂直
        type dir(const face & t) { return v() / t.v(); }    // == 0 垂直, > 0 同向
        type dis_to_face(const point & t) { return pos(t) / v().len(); }   // 在法向量上的投影
        bool equal(const face & t) { return dir(t) > 0 && pos(t).len() == 0 && pos(t[0]) == 0; }    // 面是否相等
        type volume(const point & t) { return (p::at(0) - t) * (at(1) - t) / (at(2) - t); }
    };

    struct hull : vector<face> {
        using f = vector<face>;
        hull(vector<point> t = {}) {
            if (t.size() < 4) return;   // 不允许四点共面
            shuffle(t.begin(), t.end(), rd), f::push_back({t[0], t[1], t[2]}), f::push_back({t[2], t[1], t[0]});
            for (int i = 3; i < t.size(); i++) {
                hull tmp;
                set<pair<point, point>> edge;
                for (auto & x : *this) {
                    if (x.pos(t[i]) < 0) tmp.emplace_back(x);
                    else edge.emplace(x[0], x[1]), edge.emplace(x[1], x[2]), edge.emplace(x[2], x[0]);
                }
                for (auto & [x, y] : edge) {
                    if (!edge.count({y, x})) tmp.push_back({x, y, t[i]});
                }
                swap(*this, tmp);
            }
        }
        template <class ret = type> // 2 * 表面积
        ret area(ret t = 0) { return accumulate(f::begin(), f::end(), t, [](ret t, auto & x) { return t + x.v().len(); }); }
        template <class ret = type> // 6 * 体积
        ret volume(ret t = 0) { return accumulate(f::begin(), f::end(), t, [](ret t, auto & x) { return t + x.volume({0, 0, 0}); }); }
        point centroid(point G = {}, type sum = 0) {  // 重心
            for (auto & x : *this) {
                auto ng = x[0] + x[1] + x[2];
                type nv = x[0] * x[1] / x[2];
                sum -= nv;
                G -= ng * nv;
            }
            return G / 4 / sum;
        }
    };
};


void output(__int128 x) {
    if(x == 0) {
        return;
    }
    output(x / 10);
    cout << (int)(x % 10);
}

void QAQ() {
    int n;
    cin >> n;

    vector<point<int>> a(n);

    for (int i = 0; i < n; i++) {
        cin >> a[i][0] >> a[i][1] >> a[i][2];
    }

    __int128 ans = 0;

    while (a.size() > 3) {
        point<int>::hull res(a);
        set<point<int>> s;

        ans = res.volume(ans);
        for (auto & x : res) {
            for (auto & idx : x) {
                s.emplace(idx);
            }
        }

        vector<point<int>> ta;
        for (int i = 0; i < a.size(); i++) {
            if (!s.count(a[i])) {
                ta.push_back(a[i]);
            }
        }
        swap(a, ta);
    }

    output(ans);
    cout << "\n";
}

signed main() {
    cin.tie(0) -> sync_with_stdio(0);
    cout << fixed << setprecision(12);
    int t = 1;
    cin >> t;

    while (t--) {
        QAQ();
    }
}

Details

answer.code: In member function ‘type point<type>::face::volume(const point<type>&)’:
answer.code:63:65: error: there are no arguments to ‘at’ that depend on a template parameter, so a declaration of ‘at’ must be available [-fpermissive]
   63 |         type volume(const point & t) { return (p::at(0) - t) * (at(1) - t) / (at(2) - t); }
      |                                                                 ^~
answer.code:63:65: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
answer.code:63:79: error: there are no arguments to ‘at’ that depend on a template parameter, so a declaration of ‘at’ must be available [-fpermissive]
   63 |         type volume(const point & t) { return (p::at(0) - t) * (at(1) - t) / (at(2) - t); }
      |                                                                               ^~
answer.code: In instantiation of ‘type point<type>::face::volume(const point<type>&) [with type = long long int]’:
answer.code:87:107:   required from ‘point<long long int>::hull::volume<__int128>(__int128)::<lambda(__int128, auto:29&)> [with auto:29 = point<long long int>::face]’
/usr/include/c++/13/bits/stl_numeric.h:169:22:   required from ‘_Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator<point<long long int>::face*, vector<point<long long int>::face, allocator<point<long long int>::face> > >; _Tp = __int128; _BinaryOperation = point<long long int>::hull::volume<__int128>(__int128)::<lambda(__int128, auto:29&)>]’
answer.code:87:50:   required from ‘ret point<type>::hull::volume(ret) [with ret = __int128; type = long long int]’
answer.code:125:25:   required from here
answer.code:63:67: error: ‘at’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
   63 |         type volume(const point & t) { return (p::at(0) - t) * (at(1) - t) / (at(2) - t); }
      |                                                                 ~~^~~
answer.code:63:67: note: declarations in dependent base ‘std::array<point<long long int>, 3>’ are not found by unqualified lookup
answer.code:63:67: note: use ‘this->at’ instead
answer.code:63:81: error: ‘at’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
   63 |         type volume(const point & t) { return (p::at(0) - t) * (at(1) - t) / (at(2) - t); }
      |                                                                               ~~^~~
answer.code:63:81: note: declarations in dependent base ‘std::array<point<long long int>, 3>’ are not found by unqualified lookup
answer.code:63:81: note: use ‘this->at’ instead