Submission #213449

#TimeUsernameProblemLanguageResultExecution timeMemory
213449godwindConstellation 3 (JOI20_constellation3)C++14
100 / 100
1444 ms100072 KiB
// O O O O O O O O O O O O O O O OO O OO O OO O O O TTCH O TTTCH O TTTCH O O O O #pragma GCC optimize("Ofast") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("fast-math") #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx") #include <iostream> #include <vector> #include <algorithm> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <stdio.h> #include <cstdio> #include <math.h> #include <cmath> #include <string> #include <cstring> #include <queue> #include <deque> // #include <random> #include <iomanip> #include <bitset> #include <cassert> using namespace std; #define int long long #define y1 y11 #define less less228 #define left left228 #define right right228 #define list list228 #define all(v) v.begin(), v.end() #define tm tm228 template<typename T> void uin(T &a, T b) { if (b < a) a = b; } template<typename T> void uax(T &a, T b) { if (b > a) a = b; } const int N = 228228; const int LG = 20; int n; int a[N]; int stmax[N][LG], lg[N]; void pre() { for (int i = 2; i <= n; ++i) { lg[i] = lg[i >> 1] + 1; } for (int i = 1; i <= n; ++i) { stmax[i][0] = a[i]; } for (int k = 1; (1 << k) <= n; ++k) { for (int i = 1; i <= n - (1 << k) + 1; ++i) { stmax[i][k] = max(stmax[i][k - 1], stmax[i + (1 << (k - 1))][k - 1]); } } } int getmax(int l, int r) { int k = lg[r - l + 1]; return max(stmax[l][k], stmax[r - (1 << k) + 1][k]); } pair<int,int> get_segment(int x, int y) { int l = 0, r = x; while (r - l > 1) { int mid = (l + r) >> 1; if (getmax(mid, x) >= y) l = mid; else r = mid; } pair<int, int> ans = {r, 0}; l = x, r = n + 1; while (r - l > 1) { int mid = (l + r) >> 1; if (getmax(x, mid) >= y) r = mid; else l = mid; } ans.second = l; return ans; } int forx[N]; vector<int> g[N], roots; vector< pair<int, int> > in[N]; map< pair<int, int>, vector< pair<int,int> > > mp; int take = 0; int t[N], ss = 0; void inc(int i, int dx) { for (; i < ss; i |= (i + 1)) { t[i] += dx; } } int gg = 0; int get(int i) { gg = 0; for (; i >= 0; i = (i & (i + 1)) - 1) { gg += t[i]; } return gg; } void add(int l, int r, int x) { inc(l, x); inc(r + 1, -x); } int dp[N]; int tin[N], tout[N], timer = 0; void dfs(int v) { int sums = 0; tin[v] = timer++; for (int to : g[v]) { dfs(to); sums += dp[to]; } tout[v] = timer - 1; dp[v] = sums; for (pair<int, int> pa : in[v]) { int x = pa.first, cost = pa.second; int down = forx[x]; if (down == -1 || down == v) { uax(dp[v], sums + cost); } else { uax(dp[v], sums + cost + get(tin[down])); } } int val = -dp[v] + sums; add(tin[v], tout[v], val); } vector<int> open[N], close[N]; void BuildTree() { vector< pair<int, int> > v; for (auto p : mp) { v.push_back(p.first); } int sz = (int)v.size(); ss = sz + 3; sort(all(v), [&] (pair<int, int> a, pair<int, int> b) { return a.first < b.first || (a.first == b.first && a.second > b.second); }); vector<int> left(sz, -1); vector<int> st; for (int i = sz - 1; i + 1; --i) { while (!st.empty() && v[st.back()].second <= v[i].second) { left[st.back()] = i; st.pop_back(); } st.push_back(i); } for (int i = 0; i < sz; ++i) { for (auto p : mp[v[i]]) { in[i].push_back(p); } } for (int i = 0; i < sz; ++i) { if (left[i] != -1) g[left[i]].push_back(i); else roots.push_back(i); } for (int i = 1; i <= n; ++i) { forx[i] = -1; } for (int i = 0; i < sz; ++i) { open[v[i].first].push_back(i); close[v[i].second + 1].push_back(i); } set<int> S; for (int x = 1; x <= n; ++x) { for (int i : open[x]) { S.insert(i); } for (int i : close[x]) { S.erase(i); } if (!S.empty()) forx[x] = *S.rbegin(); else forx[x] = -1; } for (int i : roots) { dfs(i); take += dp[i]; } } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; } pre(); int m; cin >> m; int all = 0; for (int i = 0; i < m; ++i) { int x, y, c; cin >> x >> y >> c; all += c; pair<int, int> pa = get_segment(x, y); mp[pa].push_back(make_pair(x, c)); } BuildTree(); cout << all - take << '\n'; return 0; } // RU_023 /* 5 1 3 4 2 3 3 1 5 3 4 3 2 2 4 2 7 5 6 2 3 6 7 6 5 7 7 5 3 3 7 3 7 10 1 7 6 4 7 8 8 6 8 5 7 3 4 2 1 10 8 2 9 6 6 7 8 3 18 5 8 17 8 5 3 5 5 3 5 4 8 1 8 13 1 7 5 7 4 13 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...