제출 #1164900

#제출 시각아이디문제언어결과실행 시간메모리
1164900SmuggingSpun송신탑 (IOI22_towers)C++20
0 / 100
29 ms17128 KiB
#include "towers.h" #include<bits/stdc++.h> using namespace std; const int lim = 1e5 + 5; const int INF = 2e9; template<class T>void maximize(T& a, T b){ if(a < b){ a = b; } } struct Node{ int cnt, l, r; Node(){ this->cnt = 0; this->l = this->r = -1; } }; int n, l_min[lim], r_min[lim], h[lim], log_v[lim], st_dif[lim << 2], spt_max[lim][17], spt_min[lim][17]; vector<Node>st; vector<pair<int, int>>a(1, make_pair(INF, -1)); int get_min(int l, int r){ int k = log_v[r - l + 1]; return min(spt_min[l][k], spt_min[r - (1 << k) + 1][k]); } int get_max(int l, int r){ int k = log_v[r - l + 1]; return max(spt_max[l][k], spt_max[r - (1 << k) + 1][k]); } void update(int id, int p){ int l = 1, r = n; while(l < r){ st[id].cnt++; int m = (l + r) >> 1; if(m < p){ st.emplace_back(st[st[id].r]); st[id].r = int(st.size()) - 1; id = st[id].r; l = m + 1; } else{ st.emplace_back(st[st[id].l]); st[id].l = int(st.size()) - 1; id = st[id].l; r = m; } } st[id].cnt++; } void build(int id = 0, int l = 1, int r = n){ if(l == r){ return; } st[id].l = st.size(); st.emplace_back(Node()); st[id].r = st.size(); st.emplace_back(Node()); int m = (l + r) >> 1; build(st[id].l, l, m); build(st[id].r, m + 1, r); } void build_dif(int id = 1, int l = 1, int r = n){ if(l == r){ st_dif[id] = 0; return; } int m = (l + r) >> 1; build_dif(id << 1, l, m); build_dif(id << 1 | 1, m + 1, r); st_dif[id] = max({st_dif[id << 1], st_dif[id << 1 | 1], get_max(m + 1, r) - get_min(l, m)}); } int get_dif(int u, int v, int id = 1, int l = 1, int r = n){ if(l > v || r < u || u > v){ return 0; } if(u <= l && v >= r){ return st_dif[id]; } int m = (l + r) >> 1; if(m >= v){ return get_dif(u, v, id << 1, l, m); } if(m < u){ return get_dif(u, v, id << 1 | 1, m + 1, r); } int temp = max({get_dif(u, v, id << 1, l, m), get_dif(u, v, id << 1 | 1, m + 1, r), get_max(m + 1, v) - get_min(u, m)}); return temp; } void init(int N, vector<int>H){ log_v[0] = -1; for(int i = 1; i < lim; i++){ log_v[i] = log_v[i >> 1] + 1; } n = N; for(int i = 0; i < n; i++){ spt_max[i + 1][0] = spt_min[i + 1][0] = h[i + 1] = H[i]; } for(int j = 1; j < 17; j++){ for(int i = 1; i + (1 << j) - 1 <= n; i++){ spt_min[i][j] = min(spt_min[i][j - 1], spt_min[i + (1 << (j - 1))][j - 1]); spt_max[i][j] = max(spt_max[i][j - 1], spt_max[i + (1 << (j - 1))][j - 1]); } } stack<int>stk; for(int i = 1; i <= n; stk.push(i++)){ while(!stk.empty() && h[i] < h[stk.top()]){ stk.pop(); } l_min[i] = (stk.empty() ? 0 : stk.top()); } while(!stk.empty()){ stk.pop(); } for(int i = n; i > 0; stk.push(i--)){ while(!stk.empty() && h[i] < h[stk.top()]){ stk.pop(); } r_min[i] = (stk.empty() ? n + 1 : stk.top()); } for(int i = 1; i <= n; i++){ a.emplace_back(min(l_min[i] == 0 ? INF : get_max(l_min[i] + 1, i), r_min[i] == n + 1 ? INF : get_max(i, r_min[i] - 1)) - h[i], i); } sort(a.begin(), a.end(), greater<pair<int, int>>()); for(auto& [u, v] : a){ cout << u << " " << v << endl; } st.assign(n + 1, Node()); build(); build_dif(); for(int i = 1; i <= n; i++){ st[i] = st[i - 1]; update(i, a[i].second); } } int get(int id, int u, int v, int l = 1, int r = n){ if(l > v || r < u){ return 0; } if(u <= l && v >= r){ return st[id].cnt; } int m = (l + r) >> 1; return get(st[id].l, u, v, l, m) + get(st[id].r, u, v, m + 1, r); } int max_towers(int l, int r, int d){ int low = 1, high = n, id = 0; while(low <= high){ int mid = (low + high) >> 1; if(a[mid].first >= d){ low = (id = mid) + 1; } else{ high = mid - 1; } } int sum = get(id, ++l, ++r); return sum; if(sum == 0){ return 1; } low = l; high = r; int L, R; while(low <= high){ int mid = (low + high) >> 1; if(get(id, l, mid) > 0){ high = (L = mid) - 1; } else{ low = mid + 1; } } low = l; high = r; while(low <= high){ int mid = (low + high) >> 1; if(get(id, mid, r) > 0){ low = (R = mid) + 1; } else{ high = mid - 1; } } int pl = 0, pr = n + (low = 1); high = L; while(low <= high){ int mid = (low + high) >> 1; if(get_max(mid, L) - d >= h[L]){ low = (pl = mid) + 1; } else{ high = mid - 1; } } low = R; high = n; while(low <= high){ int mid = (low + high) >> 1; if(get_max(R, mid) - d >= h[R]){ high = (pr = mid) - 1; } else{ low = mid + 1; } } return sum + int(get_dif(l, pl) >= d) + int(get_dif(pr, r) >= d); }
#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...