Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

Topic Link

Meaning of the questions:

Gives \ (n \) a Russian doll, each doll has set a \ (IN_I, out_i \) , and meet \ (out_i> IN_I \) . Defined doll \ (I \) can be set in the doll \ (J \) which, if and only if \ (out_i \ Leq in_j \) .
The definition of a great set of her group: if and only if there is not another set of nesting dolls on them.
Defined set of additional space for the doll \ (IN_1 + (IN_2-out_1) + \ cdots + (K-in_k-OUT_ {}. 1) \) , where \ (K \) is the maximum of the doll.
Now seeking minimal additional space are a great set of her group number.

Ideas:

The summation at the above transform equation has:
\ [in_k + \ sum_ = {I}. 1. 1} ^ {K-IN_I-out_i \]
Analysis of this formula, for a doll that is the outermost \ (K \ ) , the rest of the contribution which sets her on as \ (IN_I-out_i \) , are independent.
First of all nesting dolls by \ (in \) in ascending order, followed by an enumeration after each nesting dolls and count it as a last nesting dolls. Suppose the current enumeration \ (I \) , then the \ (DP (I) = {min_ out_j \ Leq IN_I} \ {DP (J) \} + IN_I \) , \ (DP \) store is doll the contribution value, \ (dp (i) \) represented by \ (i \) for the end of the set of her minimal additional space is.
Because the topic also requires the number of transfers when the segment tree above query, while maintaining a \ (sum \) record number, query, update, when merging nodes, merge two functions: one is to find the minimum but the number of updates, see the code.
The last time the statistics answer, to find all the great sets her group statistics.
code show as below:

#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 2e5 + 5, MOD = 1e9 + 7;
int n;
pii a[N];
struct SEG{
    struct node{
        ll Min, sum;
        node() {
            sum = 0; Min = INF;
        }
        node(ll Min, ll sum) : Min(Min), sum(sum) {}
        node operator + (const node &other) const {
            node res = node();
            if(Min < other.Min) {
                res.Min = Min;
                res.sum = sum;
            } else if(Min == other.Min) {
                res.Min = Min;
                res.sum = (other.sum + sum) % MOD;
            } else {
                res.Min = other.Min;
                res.sum = other.sum;
            }
            return res;
        }
    }t[N << 3], res;
    void build(int o, int l, int r) {
        if(l == r) {
            t[o] = node();
            return;
        }
        int mid = (l + r) >> 1;
        build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
    }
    void update(int o, int l, int r, int p, node v) {
        if(l == r) {
            t[o] = t[o] + v;
            return ;
        }
        int mid = (l + r) >> 1;
        if(p <= mid) update(o << 1, l, mid, p, v);
        else update(o << 1|1, mid + 1, r, p, v);
        t[o] = t[o << 1] + t[o << 1|1];
    }
    void query(int o, int l, int r, int L, int R) {
        if(L <= l && r <= R) {
            res = res + t[o];
            return ;
        }
        int mid = (l + r) >> 1;
        if(L <= mid) query(o << 1, l, mid, L, R);
        if(R > mid) query(o << 1|1, mid + 1, r, L, R);
    }
}seg;
int D, b[N << 1];
ll c[N], d[N];
int id(int x) {
    return lower_bound(b + 1, b + D + 1, x) - b;
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i].se >> a[i].fi;
        b[++D] = a[i].fi; b[++D] = a[i].se;
    }
    sort(a + 1, a + n + 1);
    sort(b + 1, b + D + 1);
    D = unique(b + 1, b + D + 1) - b - 1;
    ll Min = INF;
    seg.build(1, 1, D);
    for(int i = 1; i <= n; i++) {
        seg.res = SEG::node();
        seg.query(1, 1, D, 1, id(a[i].fi));
        if(seg.res.Min == INF) {
            seg.res = SEG::node(a[i].fi - a[i].se, 1);
            c[i] = 1; d[i] = a[i].fi;
            seg.update(1, 1, D, id(a[i].se), seg.res);
        } else {
            c[i] = seg.res.sum;
            d[i] = seg.res.Min + a[i].fi;
            seg.res.Min += a[i].fi - a[i].se;
            seg.update(1, 1, D, id(a[i].se), seg.res);
        }
        if(a[i].se > a[n].fi) Min = min(Min, d[i]);
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++)
        if(a[i].se > a[n].fi && d[i] == Min)
            ans = (ans + c[i]) % MOD;
    cout << ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11308217.html