QOJ.ac
QOJ
ID | Submission ID | Problem | Hacker | Owner | Result | Submit time | Judge time |
---|---|---|---|---|---|---|---|
#958 | #635663 | #9458. Triangulation | hos_lyric | ucup-team4435 | Failed. | 2024-10-13 16:58:04 | 2024-10-13 16:58:06 |
Details
Extra Test:
Accepted
time: 428ms
memory: 78944kb
input:
70 18 523990 661228 542094 867454 715348 957693 724847 921955 185285 504782 340889 164109 548808 628313 528132 176875 403401 165509 733176 362440 62653 306280 841647 146408 169951 295342 186442 591918 405268 31651 207390 724432 622724 775650 495011 800641 0 348636 601903 824557 560907 777784 213259 ...
output:
15538001 1 15069133 1 17917420 1 16001978 1 17031503 1 16877354 1 14654876 1 16538641 1 17612992 1 16472785 1 19422464 1 19032907 1 16539162 1 13871655 1 13016693 1 19112456 1 19655573 1 17515583 1 18004921 1 18021001 1 15684805 1 16002463 1 15681064 1 15314722 1 14193869 1 17757963 1 17751846 1 137...
result:
ok 70 lines
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;
}