제출 #1258204

#제출 시각아이디문제언어결과실행 시간메모리
1258204madamadam33개의 봉우리 (IOI25_triples)C++20
82.40 / 100
318 ms34092 KiB
#include "triples.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>; using pi = pair<int, int>; #define FOR(i, a, b) for (int i = a; i < b; i++) #define ROF(i, a, b) for (int i = a; i >= b; i--) #define each(a, x) for (auto &a : x) #define all(x) (x).begin(), (x).end() #define bg(x) (x).begin() #define en(x) (x).end() #define rev(x) reverse(all(x)) #define sz(x) int((x).size()) #define srt(x) sort(all(x)) #define cnt(a, x) count(all(x), a) #define trace(x) each(a, (x)) cout << a << " " #define mp make_pair #define pb push_back #define lb lower_bound #define ub upper_bound ll brute(vi h) { int n = sz(h); ll ans = 0; FOR(i, 0, n) { FOR(j, i+1, n) { FOR(k, j+1, n) { int d1 = min({k-j, k-i,j-i}), d3 = max({k-j, j-i, k-i}), f1 = min({h[i], h[j], h[k]}), f3 = max({h[i], h[j], h[k]}); int d2 = (k-j) ^ (k-i) ^ (j-i) ^ d1 ^ d3, f2 = h[i] ^ h[j] ^ h[k] ^ f1 ^ f3; if (d1 == f1 && d2 == f2 && d3 == f3) ans++; } } } return ans; } struct Triple { int i, j, k; Triple() {}; Triple(int I, int J, int K) { i = min({I, J, K}); k = max({I, J, K}); j = (I ^ J ^ K) ^ i ^ k; // lol } const bool operator<(const Triple &other) const { if (i != other.i) return i < other.i; if (j != other.j) return j < other.j; return k < other.k; } }; ll count_triples(vi h) { int n = sz(h); ll ans = 0; FOR(i, 0, n) { // count number of triples where h[i] = d(i, j) or d(i, k) int H = h[i]; set<Triple> trips; // prevent double count with dupe height int j = i + H; if (j < n) { int k1 = i + h[j], k2 = j + h[j]; // 2 cases — h[j] = d(i, k) or h[j] = d(j, k) if (k1 < n && h[k1] == (k1 - j)) trips.insert(Triple(i, j, k1)); // we know d(i, j) and d(i, k) to be h[i] and h[j], so does h[k] == d(j, k) if (k2 < n && h[k2] == (k2 - i)) trips.insert(Triple(i, j, k2)); // symmetric but this time for i } int k = i + H; if (k < n) { int j1 = i + h[k], j2 = k - h[k]; // h[k] = d(i, k), h[k] = d(j, k) if ((i < j1 && j1 < k) && h[j1] == (k - j1)) trips.insert(Triple(i, j1, k)); if ((i < j2 && j2 < k) && h[j2] == (j2 - i)) trips.insert(Triple(i, j2, k)); } for (auto &el : trips) { if (h[el.j] != h[el.i] && h[el.k] != h[el.i]) ans++; } } unordered_map<int, vector<int>> pc, nc; // positive line intercepts, negative line intercepts vi inp(n), inn(n); // lookup for the intercept FOR(i, 0, n) { int c1 = h[i] - i, c2 = h[i] + i; inp[i] = c1, inn[i] = c2; pc[c1].pb(i), nc[c2].pb(i); } for (auto &cnst : pc) { // count number of triples where h[j] = d(i, j), h[k] = d(i, k), and h[i] = d(j, k) = h[k] - h[j] int i = -cnst.first; if (i < 0 || i >= n) continue; int H = h[i]; for (auto &el : cnst.second) { int j = el, k = el + H; if (k >= n) break; if (inp[k] != inp[j]) continue; ans++; } } FOR(j, 0, n) { // count number of triples where h[j] = d(i, k), h[k] = d(i, j) and h[i] = d(j, k) = h[j] - h[k] int f1 = lower_bound(all(pc[inp[j]]), j-h[j]) - bg(pc[inp[j]]); int f2 = upper_bound(all(nc[inn[j]]), j+h[j]) - bg(nc[inn[j]]); int p1 = lower_bound(all(pc[inp[j]]), j) - bg(pc[inp[j]]), p2 = lower_bound(all(nc[inn[j]]), j) - bg(nc[inn[j]]); if (p1 - f1 < f2 - p2) { // there is no way to set up the diagonals such that no matter which way you go its n^2 for (int el = f1; el < p1; el++) { int i = pc[inp[j]][el]; int dist = j - i; if (j + h[i] >= n || h[j + h[i]] != dist) continue; ans++; } } else { for (int el = p2 + 1; el < f2; el++) { int k = nc[inn[j]][el]; int dist = k - j; if (j - h[k] < 0 || h[j - h[k]] != dist) continue; ans++; } } } return ans; } bool accept(double cur_score, double next_score, double temp, mt19937 &rng) { if (next_score > cur_score) return true; cur_score = -cur_score; next_score = -next_score; double prob = exp(-(next_score - cur_score) / temp); return generate_canonical<double, 53>(rng) < prob; } vi construct_range(int M, int K) { vi cur = {3, 1, 2, 1, 4, 5, 4, 3, 8, 7, 6, 9, 12, 3, 10, 5, 1, 7, 14, 9, 4, 11, 18, 23, 8, 15, 26, 23, 24, 25, 20, 21, 22, 17, 18, 19, 4, 13, 14, 15, 1, 9, 10, 11, 40, 5, 6, 7, 38, 3, 4, 1, 2, 1, 3, 15, 6, 25, 26, 27, 10, 21, 22, 23, 14, 25, 16, 17, 18, 15, 16, 21, 18, 19, 4, 1, 6, 7, 8, 5, 2, 3, 4, 1, 2, 1, 4, 3, 2, 3, 1, 1, 2, 4, 3, 6, 5, 6, 7, 2, 3, 4, 1, 2, 1, 8, 3, 6, 5, 4, 21, 20, 21, 15, 17, 18, 15, 16, 13, 14, 11, 12, 25, 10, 23, 22, 21, 22, 19, 40, 39, 40, 1, 36, 37, 34, 35, 32, 33, 48, 7, 40, 45, 38, 43, 42, 41, 34, 57, 58, 19, 18, 19, 52, 51, 50, 25, 24, 11, 28, 27, 60, 15, 58, 17, 16, 15, 20, 37, 36, 1, 80, 75, 4, 73, 6, 75, 86, 9, 8, 83, 9, 81, 80, 3, 36, 77, 18, 17, 58, 57, 60, 59, 12, 93, 26, 9, 66, 65, 108, 109, 100, 105, 106, 103, 104, 101, 102, 39, 38, 41, 40, 81, 122, 33, 110, 47, 30, 117, 32, 89, 88, 41, 92, 91, 38, 21, 80, 23, 58, 99, 62, 61, 102, 29, 66, 65, 50, 69, 70, 69, 60, 73, 72, 57, 64, 41, 60, 61, 2, 69, 64, 83, 48, 83, 8, 51, 52, 77, 78, 55, 74, 75, 3, 43, 60, 35, 20, 47, 18, 65, 66, 21, 52, 27, 12, 25, 30, 31, 28, 29, 34, 19, 32, 53, 22, 23, 8, 37, 26, 3, 44, 45, 42, 7, 8, 33, 10, 11, 36, 37, 8, 1, 16, 3, 4, 19, 52, 1, 16, 9, 24, 3, 12, 21, 22, 9, 8, 17, 18, 5, 14, 13, 14, 6, 10, 11, 8, 4, 5, 5, 6, 3, 1, 10, 11, 1, 8, 14, 7, 6, 17, 10, 9, 8, 13, 12, 23, 4, 3, 26, 19, 6, 7, 22, 3, 32, 13, 12, 55, 28, 27, 58, 31, 40, 5, 22, 21, 36, 35, 18, 37, 48, 15, 30, 29, 44, 43, 26, 9, 56, 23, 38, 37, 52, 51, 34, 17, 64, 31, 46, 45, 60, 59, 70, 25, 8, 73, 66, 65, 76, 69, 68, 33, 16, 59, 82, 83, 62, 85, 78, 79, 8, 81, 80, 83, 82, 71, 72, 75, 74, 69, 76, 71, 66, 73, 38, 67, 8, 41, 60, 43, 62, 29, 30, 65, 16, 33, 50, 51, 36, 53, 22, 55, 8, 25, 42, 43, 28, 45, 14, 47, 48, 17, 34, 35, 20, 37, 6, 39, 40, 9, 26, 27, 12, 29, 4, 3, 32, 5, 6, 19, 2, 3, 14, 23, 12, 13, 16, 15, 10, 17, 12, 7, 14, 9, 12, 11, 12, 1, 8, 3, 2, 5, 4, 5, 2, 3, 6, 1}; vi ret; while (ret.size() < M) { for (auto &el : cur) { ret.pb(el); if (ret.size() >= M) break; } } return ret; // vi cur(M, 1), best(M, 1); // int score = 0, best_score = 0; // score = 0; // // double T = 10000, u = 0.9995; // double t0 = 100.0; double c = 0.75; // int trials = 1; // mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); // uniform_int_distribution u(0, M-1); // geometric_distribution<int> g(0.4); // double lambda = 0.01; vector<double> w(M); for (int i = 0; i < M; i++) w[i] = exp(-lambda * i); // discrete_distribution<int> d(all(w)); // // while (T > 1) { // while(best_score < K) { // if (trials % 25000 == 0) cerr << "Trials: " << trials << " Best: " << best_score << "\n"; // if (trials % CHECK_EVERY == 0) save_checkpoint(CHECKPOINT_PATH, best, best_score, trials); // double T = c / log(t0 + double(trials)); // vi nxt = cur; // int idx = u(rng); // // int val = g(rng) + 1; while (val >= M) val = g(rng) + 1; // int val = d(rng); while (!(1 <= val && val < M)) val = d(rng); // nxt[idx] = val; // int ns = count_triples(nxt); // if (accept(score, ns, T, rng)) { // score = ns; cur = nxt; // if (ns > best_score) { // best_score = ns; best = nxt; // } // } // // T *= u; // trials++; // } // cerr << "Array has: " << count_triples(best) << " triples.\n"; // return best; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...