제출 #1258218

#제출 시각아이디문제언어결과실행 시간메모리
1258218madamadam33개의 봉우리 (IOI25_triples)C++20
83.26 / 100
319 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 = {1, 7, 6, 7, 4, 5, 6, 7, 8, 1, 2, 1, 4, 3, 2, 7, 6, 4, 5, 3, 7, 2, 1, 3, 3, 2, 5, 4, 7, 16, 9, 8, 19, 12, 11, 14, 15, 24, 7, 26, 9, 20, 19, 22, 21, 24, 15, 26, 25, 7, 1, 4, 21, 8, 3, 10, 5, 8, 7, 14, 9, 12, 11, 2, 15, 52, 15, 6, 55, 4, 47, 58, 51, 50, 43, 48, 53, 46, 51, 66, 49, 60, 59, 62, 61, 64, 55, 64, 57, 28, 59, 26, 31, 48, 29, 22, 45, 84, 25, 50, 49, 80, 79, 38, 77, 40, 75, 34, 43, 36, 87, 38, 39, 68, 83, 66, 65, 66, 87, 46, 3, 60, 61, 58, 59, 56, 3, 54, 55, 12, 7, 14, 9, 16, 11, 62, 13, 14, 115, 66, 113, 110, 111, 2, 121, 4, 5, 2, 3, 32, 33, 128, 29, 30, 89, 124, 95, 40, 85, 94, 37, 20, 21, 18, 19, 16, 15, 16, 13, 96, 109, 26, 107, 24, 23, 152, 103, 28, 27, 148, 63, 2, 1, 60, 67, 68, 141, 64, 65, 8, 7, 74, 51, 12, 49, 72, 47, 56, 81, 54, 127, 78, 51, 62, 63, 60, 133, 58, 57, 58, 69, 146, 67, 30, 65, 64, 35, 36, 35, 146, 23, 148, 149, 42, 41, 28, 153, 30, 155, 24, 49, 34, 35, 132, 93, 30, 91, 120, 41, 88, 99, 124, 97, 170, 127, 94, 123, 124, 5, 108, 133, 106, 1, 112, 11, 182, 115, 116, 113, 114, 79, 110, 121, 114, 119, 114, 13, 116, 71, 88, 87, 240, 7, 92, 91, 94, 95, 94, 95, 134, 99, 84, 101, 86, 87, 88, 109, 214, 91, 148, 93, 146, 219, 144, 143, 44, 31, 116, 225, 226, 57, 104, 37, 24, 61, 108, 165, 64, 65, 128, 127, 46, 59, 70, 197, 50, 63, 120, 53, 54, 53, 180, 57, 178, 59, 46, 175, 144, 85, 50, 65, 52, 191, 6, 189, 190, 187, 186, 187, 74, 97, 160, 159, 146, 93, 92, 67, 164, 9, 152, 23, 86, 171, 170, 15, 16, 17, 114, 79, 20, 163, 22, 109, 6, 7, 8, 123, 2, 3, 4, 1, 2, 1, 28, 9, 4, 37, 6, 5, 65, 3, 2, 55, 118, 117, 28, 9, 8, 49, 24, 111, 22, 21, 20, 129, 130, 17, 40, 15, 72, 2, 36, 123, 34, 33, 32, 35, 30, 29, 4, 27, 13, 10, 11, 87, 17, 21, 15, 53, 92, 81, 50, 49, 1, 10, 12, 99, 44, 4, 72, 59, 92, 93, 68, 77, 66, 65, 64, 73, 62, 61, 70, 59, 45, 79, 43, 77, 76, 75, 76, 73, 72, 73, 70, 17, 33, 32, 44, 60, 64, 28, 39, 64, 26, 62, 67, 64, 65, 55, 32, 72, 5, 70, 49, 37, 51, 54, 53, 54, 47, 43, 44, 84, 59, 82, 87, 15, 89, 2, 87, 35, 20, 94, 69, 92, 71, 94, 95, 100, 67, 98, 6, 104, 15, 102, 81, 5, 19, 84, 77, 88, 87, 11, 12, 92, 91, 137, 6, 7, 87, 122, 123, 120, 121, 1, 37, 53, 39, 2, 131, 42, 129, 44, 109, 110, 69, 6, 49, 140, 51, 138, 119, 118, 55, 18, 27, 20, 59, 150, 17, 148, 127, 154, 23, 152, 123, 30, 35, 160, 33, 158, 137, 36, 161, 34, 141, 40, 25, 38, 137, 28, 5, 15, 175, 86, 173, 10, 15, 146, 13, 18, 5, 16, 95, 58, 59, 20, 11, 56, 3, 158, 15, 6, 67, 4, 3, 10, 109, 80, 7, 78, 199, 4, 115, 38, 39, 118, 35, 90, 33, 34, 49, 86, 47, 28, 29, 90, 25, 42, 87, 22, 223, 56, 221, 18, 19, 34, 51, 226, 31, 68, 207, 66, 27, 210, 43, 70, 111, 40, 109, 108, 65, 36, 1, 156, 79, 60, 71, 50, 57, 74, 9, 54, 87, 64, 69, 50, 91, 60, 141, 18, 17, 86, 137, 14, 59, 178, 81, 102, 9, 28, 27, 106, 75, 32, 31, 90, 71, 60, 19, 38, 37, 84, 23, 40, 159, 80, 157, 10, 29, 164, 49, 14, 107, 128, 53, 52, 135, 20, 101, 134, 23, 4, 97, 44, 139, 64, 131, 10, 31, 134, 13, 6, 35, 108, 129, 118, 127, 126, 21, 114, 123, 78, 25, 46, 119, 128, 21, 50, 11, 70, 33, 90, 15, 36, 29, 12, 95, 96, 61, 98, 97, 24, 101, 100, 21, 86, 87, 9, 51, 72, 27, 92, 47, 68, 15, 78, 9, 80, 41, 62, 83, 38, 15, 58, 67, 68, 3, 70, 63, 64, 73, 66, 49, 26, 69, 58, 23, 60, 55, 74, 63, 18, 17, 60, 37, 68, 47, 49, 49, 42, 43, 52, 45, 55, 189, 48, 40, 51, 35, 34, 53, 32, 46, 34, 39, 67, 37, 30, 70, 44, 11, 55, 66, 75, 58, 77, 17, 61, 19, 63, 74, 22, 66, 67, 68, 69, 27, 6, 72, 8, 92, 5, 11, 29, 3, 2, 98, 11, 5, 83, 3, 7, 6, 10, 10, 89, 108, 13, 5, 23, 16, 15, 26, 19, 18, 99, 22, 21, 24, 121, 12, 27, 26, 15, 108, 127, 128, 129, 20, 3, 22, 23, 6, 25, 118, 3, 120, 11, 44, 43, 8, 9, 10, 5, 50, 37, 8, 5, 6, 1, 2, 43, 20, 1, 28, 59, 2, 25, 26, 73, 22, 53, 20, 31, 68, 17, 28, 15, 14, 73, 62, 23, 76, 41, 78, 79, 38, 29, 70, 53, 72, 33, 50, 31, 30, 47, 54, 55, 6, 63, 42, 65, 60, 61, 62, 57, 58, 59, 16, 57, 52, 53, 54, 51, 10, 51, 16, 25, 48, 27, 4, 29, 30, 19, 8, 33, 10, 35, 36, 37, 6, 27, 12, 9, 30, 31, 16, 13, 14, 23, 24, 17, 6, 19, 20, 21, 4, 5, 2, 3, 8, 1, 10, 11, 12, 3, 6, 5, 6, 7, 2, 3, 4, 1, 2, 1, 3, 3, 2}; 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...