답안 #213444

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
213444 2020-03-25T20:23:50 Z godwind 별자리 3 (JOI20_constellation3) C++14
0 / 100
19 ms 22016 KB
// 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;
    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

 
 
*/
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 22016 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 22016 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 22016 KB Output isn't correct
2 Halted 0 ms 0 KB -