#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |