QOJ.ac
QOJ
The 2nd Universal Cup Finals is coming! Check out our event page, schedule, and competition rules!
ID | Submission ID | Problem | Hacker | Owner | Result | Submit time | Judge time |
---|---|---|---|---|---|---|---|
#953 | #635663 | #9458. Triangulation | hos_lyric | ucup-team4435 | Failed. | 2024-10-13 16:06:02 | 2024-10-13 16:06:02 |
Details
Extra Test:
Invalid Input
input:
70 18 862483 71849 250768 41909 431141 439685 485976 19747 901844 726620 586459 23369 984550 367693 783903 369385 587698 272505 241045 957317 863491 945419 13288 860966 499743 971134 447555 430818 3475 610084 123691 83109 453248 388769 237082 39949 225286 797387 751042 987849 525693 384726 521046 22...
output:
result:
FAIL w[1][1] must equal to 0
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#635663 | #9458. Triangulation | ucup-team4435# | TL | 85ms | 79068kb | C++20 | 11.3kb | 2024-10-12 20:32:19 | 2024-10-13 18:02:34 |
answer
#include "bits/stdc++.h"
#ifdef LOCAL
#include "debug.h"
#else
#define dbg(...)
#define dprint(...)
#define debug if constexpr (false)
#define draw_tree(...)
#define draw_array(...)
#endif // LOCAL
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;
int Bit(int mask, int b) { return (mask >> b) & 1; }
template<class T>
bool ckmin(T &a, const T &b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<class T>
bool ckmax(T &a, const T &b) {
if (b > a) {
a = b;
return true;
}
return false;
}
// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
--l;
while (r - l > 1) {
T mid = l + (r - l) / 2;
if (predicat(mid)) {
r = mid;
} else {
l = mid;
}
}
return r;
}
template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
return FindFirstTrue(l, r, predicat) - 1;
}
const ll INF = 2e18;
const int INFi = 2e9;
bool Equal(ll A, ll B) {
return A == B;
}
bool Less(ll A, ll B) {
return A < B;
}
bool Greater(ll A, ll B) {
return A > B;
}
bool LessOrEqual(ll A, ll B) {
return A <= B;
}
bool GreaterOrEqual(ll A, ll B) {
return A >= B;
}
const ld EPS = 1e-9;
bool Equal(ld A, ld B) {
return abs(A - B) < EPS;
}
bool Less(ld A, ld B) {
return A + EPS < B;
}
bool Greater(ld A, ld B) {
return A > B + EPS;
}
bool LessOrEqual(ld A, ld B) {
return A <= B + EPS;
}
bool GreaterOrEqual(ld A, ld B) {
return A + EPS >= B;
}
template<typename T, typename Q>
bool LessOrEqual(T A, Q B) {
using C = std::common_type_t<T, Q>;
return LessOrEqual(static_cast<C>(A), static_cast<C>(B));
}
template<typename T, typename Q>
bool Equal(T A, Q B) {
using C = std::common_type_t<T, Q>;
return Equal(static_cast<C>(A), static_cast<C>(B));
}
template<typename T, typename Q>
bool Less(T A, Q B) {
using C = std::common_type_t<T, Q>;
return Less(static_cast<C>(A), static_cast<C>(B));
}
template<typename T, typename Q>
bool Greater(T A, Q B) {
using C = std::common_type_t<T, Q>;
return Greater(static_cast<C>(A), static_cast<C>(B));
}
template<typename T, typename Q>
bool GreaterOrEqual(T A, Q B) {
using C = std::common_type_t<T, Q>;
return GreaterOrEqual(static_cast<C>(A), static_cast<C>(B));
}
template<typename T>
ll sgn(T x) {
if (Equal(x, 0)) return 0;
return Less(x, 0) ? -1 : 1;
}
template<typename T>
struct Point {
T x;
T y;
Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {}
template<typename Q>
Point(const Point<Q> &other) {
x = static_cast<T>(other.x);
y = static_cast<T>(other.y);
}
template<typename Q>
Point(Point<Q> &&other) {
x = static_cast<T>(other.x);
y = static_cast<T>(other.y);
}
template<typename Q>
Point<std::common_type_t<T, Q>> operator+(const Point<Q> &oth) const {
return Point{x + oth.x, y + oth.y};
}
template<typename Q>
Point<std::common_type_t<T, Q>> operator-(const Point<Q> &oth) const {
return {x - oth.x, y - oth.y};
}
template<typename Q>
bool operator==(const Point<Q> &oth) const {
return x == oth.x && y == oth.y;
}
template<typename Q>
bool operator<(const Point<Q> &oth) const {
return make_pair(x, y) < make_pair(oth.x, oth.y);
}
template<typename Q>
requires (is_integral_v<Q> || is_floating_point_v<Q>)
Point<std::common_type_t<Q, T>> operator*(const Q &b) const {
return {x * b, y * b};
}
template<typename Q>
requires (is_integral_v<Q> || is_floating_point_v<Q>)
Point<ld> operator/(const Q &b) const {
return {(ld) x / b, (ld) y / b};
}
template<typename Q>
std::common_type_t<Q, T> operator*(const Point<Q> &oth) const {
return x * oth.y - y * oth.x;
}
template<typename Q>
std::common_type_t<Q, T> operator%(const Point<Q> &oth) const {
return x * oth.x + y * oth.y;
}
Point &operator+=(const Point &other) {
x += other.x;
y += other.y;
return *this;
}
Point &operator-=(const Point &other) {
x -= other.x;
y -= other.y;
return *this;
}
friend ostream &operator<<(ostream &stream, const Point &P) {
stream << P.x << ' ' << P.y;
return stream;
}
friend istream &operator>>(istream &stream, Point &P) {
stream >> P.x >> P.y;
return stream;
}
};
template<typename T>
Point<T> rotateCW(const Point<T> &P) {
return {P.y, -P.x};
}
template<typename T>
Point<T> rotateCCW(const Point<T> &P) {
return {-P.y, P.x};
}
template<typename T, typename Q>
bool Equal(const Point<T> &a, const Point<Q> &b) {
return Equal(a.x, b.x) && Equal(a.y, b.y);
}
template<typename T, typename Q>
bool Less(const Point<T> &a, const Point<Q> &b) {
if (!Equal(a.x, b.x)) return Less(a.y, b.y);
return Less(a.y, b.y);
}
template<typename T, typename Q>
bool Greater(const Point<T> &a, const Point<Q> &b) {
if (!Equal(a.x, b.x)) return Greater(a.y, b.y);
return Greater(a.y, b.y);
}
template<typename T>
Point<T> operator-(const Point<T> &a) {
return {-a.x, -a.y};
}
template<typename T>
T len2(const Point<T> &a) {
return a % a;
}
template<typename T>
ld len(const Point<T> &a) {
return sqrtl(len2(a));
}
template<typename T, typename Q>
T dist2(const Point<T> &a, const Point<Q> &b) {
return len2(a - b);
}
template<typename T, typename Q>
ld dist(const Point<T> &a, const Point<Q> &b) {
return len(a - b);
}
using pt = Point<ll>;
template<typename T, typename U>
bool VComp(const Point<T> &a, const Point<U> &b) {
bool upA = a.y > 0 || (a.y == 0 && a.x >= 0);
bool upB = b.y > 0 || (b.y == 0 && b.x >= 0);
if (upA != upB) return upA;
auto val = a * b;
if (val != 0) return val > 0;
return len2(a) < len2(b);
}
template<typename T, typename U>
bool VCompNoLen(const Point<T> &a, const Point<U> &b) {
bool upA = a.y > 0 || (a.y == 0 && a.x >= 0);
bool upB = b.y > 0 || (b.y == 0 && b.x >= 0);
if (upA != upB) return upA;
auto val = a * b;
return val > 0;
}
const int LG = 18;
const int N = 1 << LG;
pair<ll, ll> dp[N][LG];
bool valid[LG][LG][LG];
void add(int i, int j, pair<ll, ll> ways, ll cost) {
ways.first += cost;
if (dp[i][j].first < ways.first) return;
if (dp[i][j].first > ways.first) {
dp[i][j].first = ways.first;
dp[i][j].second = 0;
}
dp[i][j].second += ways.second;
}
int GetBit(int mask, int b) {
return (mask >> b) & 1;
}
vector<pt> a;
vector<vl> w;
int n;
vi was;
pair<ll, ll> solve(int mask, int b) {
if (dp[mask][b].second != -1) return dp[mask][b];
was.push_back(mask);
dp[mask][b].second = 0;
int pr = b - 1;
int nx = b + 1;
while (pr >= 0 && !GetBit(mask, pr)) pr--;
while (nx < n && !GetBit(mask, nx)) nx++;
if (nx != n) {
add(mask, b, solve(mask, nx), 0);
for(int t = b + 1; t < nx; ++t) {
if (valid[b][t][nx] && (a[nx] - a[b]) * (a[t] - a[b]) > 0) {
add(mask, b, solve(mask ^ (1 << t), b), w[t][nx] + w[t][b]);
dbg(mask, b, dp[mask][b], t);
}
}
if (pr != -1) {
if (valid[pr][b][nx] && (a[b] - a[pr]) * (a[nx] - a[pr]) > 0) {
add(mask, b, solve(mask ^ (1 << b), pr), w[pr][nx]);
dbg(mask, b, dp[mask][b], -1);
}
}
}
dbg(mask, b, dp[mask][b]);
return dp[mask][b];
}
template<typename T>
bool inside(Point<T> a, Point<T> b, Point<T> c, Point<T> d) {
auto area = [&](auto v1, auto v2) {
return abs(v1 * v2);
};
return area(b - a, c - a) == area(a - d, b - d) + area(b - d, c - d) + area(c - d, a - d);
}
void solve() {
cin >> n;
a.resize(n);
rep(i, n) cin >> a[i];
w.assign(n, vl(n));
rep(i, n) {
rep(j, n) {
cin >> w[i][j];
}
}
{
vi ord(n);
iota(all(ord), 0);
sort(all(ord), [&](const int &i, const int &j) { return a[i] < a[j]; });
vector<pt> b(n);
rep(i, n) b[i] = a[ord[i]];
vector<vl> ww(n, vl(n));
rep(i, n) {
rep(j, n) {
ww[i][j] = w[ord[i]][ord[j]];
}
}
swap(a, b);
swap(w, ww);
}
memset(valid, 0, sizeof(valid));
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
bool ok = true;
for (int x = 0; x < n; x++) {
if (x == i || x == j || x == k) {
continue;
}
if (inside(a[i], a[j], a[k], a[x])) {
ok = false;
break;
}
}
valid[i][j][k] = ok;
}
}
}
{
vi stk;
stk.push_back(0);
for (int i = 1; i < n; ++i) {
while (stk.size() >= 2 &&
(a[stk[stk.size() - 1]] - a[stk[stk.size() - 2]]) * (a[i] - a[stk[stk.size() - 2]]) > 0) {
stk.pop_back();
}
stk.push_back(i);
}
int mask = 0;
for (auto &i: stk) mask |= (1 << i);
dp[mask][n - 1] = {0, 1};
was.push_back(mask);
}
{
vi stk;
stk.push_back(0);
for (int i = 1; i < n; ++i) {
while (stk.size() >= 2 &&
(a[stk[stk.size() - 1]] - a[stk[stk.size() - 2]]) * (a[i] - a[stk[stk.size() - 2]]) < 0) {
stk.pop_back();
}
stk.push_back(i);
}
int mask = 0;
for (auto &i: stk) mask |= (1 << i);
ll res = 0;
for(int i = 1; i < stk.size(); ++i) res += w[stk[i - 1]][stk[i]];
auto ans = solve(mask, 0);
ans.first += res;
cout << ans.first << ' ' << ans.second << '\n';
}
for(auto &mask : was) {
rep(i, n) dp[mask][i] = {INF, -1};
}
was.clear();
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(12) << fixed;
int t = 1;
rep(i, N) rep(j, LG) dp[i][j] = {INF, -1};
cin >> t;
rep(i, t) {
solve();
}
return 0;
}