제출 #1249534

#제출 시각아이디문제언어결과실행 시간메모리
1249534qwerasdfzxclTriple Peaks (IOI25_triples)C++20
100 / 100
1118 ms42820 KiB
#include "triples.h" #include <bits/stdc++.h> using namespace std; using ll = long long; constexpr int INF1 = 1e9 + 100; long long count_triples(std::vector<int> H){ int N = H.size(); vector<int> X(N), Y(N), cnt(N*3); vector<vector<int>> buf(N*3), Q(N*3); ll ans = 0; for (int i=0;i<N;i++){ X[i] = i - H[i] + N, Y[i] = i + H[i] + N; buf[X[i]].push_back(Y[i]); } for (int i=0;i<N;i++){ // O(Nsqrt(N)) if (buf[X[i]].size() > buf[Y[i]].size()) Q[X[i]].push_back(Y[i]); else Q[Y[i]].push_back(X[i]); } for (int i=0;i<N*3;i++) if (!Q[i].empty()){ for (auto &j:Q[i]){ for (auto &y:buf[j]) cnt[y]++; } for (auto &y:buf[i]) ans += cnt[y]; for (auto &j:Q[i]){ for (auto &y:buf[j]) cnt[y]--; } } // O(N) bruteforce auto valid = [&](int i, int j, int k){ if (!(0 <= i && i < j && j < k && k < N)) return 0; int a[3] = {j-i, k-j, k-i}; int b[3] = {H[i], H[j], H[k]}; sort(a, a+3); sort(b, b+3); for (int t=0;t<3;t++) if (a[t] != b[t]) return 0; return 1; }; for (int i=0;i<N;i++){ // case 1: H[i] is the longest int k = i + H[i]; if (k < 0 || k >= N) continue; int j = i + H[k]; // case 1-1 ans += valid(i, j, k); if (j != k - H[k]){ // case 1-2 j = k - H[k]; ans += valid(i, j, k); } } for (int k=0;k<N;k++){ // case 2: H[k] is the longest int i = k - H[k]; if (i < 0 || i >= N) continue; int j = i + H[i]; // case 2-1 ans += valid(i, j, k); if (j != k - H[i]){ // case 2-2 j = k - H[i]; ans += valid(i, j, k); } } for (int i=0;i<N;i++){ // case 3: H[j] is the longest int j = i + H[i]; if (j < 0 || j >= N) continue; int k = i + H[j]; if (j-i != k-j){ ans += valid(i, j, k); } } return ans; } std::vector<int> construct_range(int M, int K){ int N = M; vector<int> X = {-1}, Y = {1}, used(N*2), C = {0}, H(N), V(N*2, -INF1); for (int i=2;i<N*2;i+=2) V[i] = 1; while(true){ auto it = max_element(V.begin(), V.end()); int mx = *it, opt = it - V.begin(); if (mx==0) break; for (auto &x:C){ if (x+opt < N*2 && !used[x+opt]){ used[x+opt] = 1; if (x < opt){ X.push_back(x); Y.push_back(opt); } else{ X.push_back(opt); Y.push_back(x); } for (auto &y:C){ int z = x+opt - y; if (0 <= z && z < N*2) V[z]--; } } } for (int i=0;opt+i<N*2;i+=2) if (!used[opt+i]) V[i]++; C.push_back(opt); V[opt] = -INF1; } assert((int)X.size() == N); for (int i=0;i<N;i++) H[(X[i] + Y[i]) / 2] = (Y[i] - X[i]) / 2; ll cnt = count_triples(H); while(cnt < K){ for (int i=0;i<N;i++){ for (int j=1;j<=N-1;j++){ int tmp = H[i]; H[i] = j; ll cnt2 = count_triples(H); if (cnt2 > cnt) cnt = cnt2; else H[i] = tmp; } } } return H; }
#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...