bzoj5017 [Snoi2017] bomb (FIG segment tree by Optimized +) + Tarjan condensing point Topological Sort

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=5017

answer

The subject method for a lot of.

Optimization of the construction segment tree diagram

Optimized construction segment tree diagram approach should be quite obvious that a bomb can be detonated bombs inside is clearly a range of directly to the tree line in this range were optimized to build map.

Such a ring can be obtained with a view point of reduction can be fried to the bomb after bomb is from this point can go point.

But this is not very good to do, but you can also find a range of final bomb, it can be determined about the endpoint after shrinking by DAG point.

Time complexity \ (O (n-\ log n-) \) , the space complexity \ (O (n-\ log n-) \) .


General Construction Plan

Can be found at one point can be fried to a bomb, only the bombs inside the left point and the right point of maximum minimum bombs around the real final answer will contribute to the endpoint.

Direct the two sides will be able to build a bomb, then same as above, to shrink tarjan point, then ran out on the DAG about the endpoint.

But because you want to determine the position of the left and right end points correspond, so the \ (log \) still no way to get rid of.

Time complexity \ (O (n-\ log n-) \) , the space complexity \ (O (n-) \) .


Fairy linear recursion approach

https://www.cnblogs.com/saigyouji-yuyuko/p/11771364.html

Throw a link on foot.

I will not, it seems very fairy look.

I heard that time and space are linear, oh.


#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; //typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 500000 + 7;
const int M = 500000 * 2 + 7;
const int P = 1e9 + 7;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int LOG = 19;

typedef std::pair<ll, int> pii;

int n, m, sccno, dfc, tp;
int dfn[N], low[N], scc[N], s[N];
std::vector<int> v[N];
ll a[N], r[N], dpl[N], dpr[N];
pii minl[N][LOG], maxr[N][LOG];

struct Edge { int to, ne; } g[M]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); }

inline void dfs(int x) {
    dfn[x] = low[x] = ++dfc, s[++tp] = x;
    for fec(i, x, y) if (!dfn[y]) dfs(y), smin(low[x], low[y]);
    else if (!scc[y]) smin(low[x], dfn[y]);
    if (low[x] == dfn[x]) {
        ++sccno;
        dpl[sccno] = INF, dpr[sccno] = -INF;
        while (1) {
            int y = s[tp--];
            scc[y] = sccno, smax(dpr[scc[y]], a[y] + r[y]), smin(dpl[scc[y]], a[y] - r[y]);
            v[scc[y]].pb(y);
            if (x == y) break;
        }
    }
}
inline void tarjan() {
    for (int i = 1; i <= n; ++i)
        if (!dfn[i]) dfs(i);
}

inline void rmq_init() {
    for (int i = 1; i <= n; ++i) minl[i][0] = pii(a[i] - r[i], i), maxr[i][0] = pii(a[i] + r[i], i);
    for (int j = 1; (1 << j) <= n; ++j)
        for (int i = 1; i + (1 << j) - 1 <= n; ++i)
            minl[i][j] = std::min(minl[i][j - 1], minl[i + (1 << (j - 1))][j - 1]),
            maxr[i][j] = std::max(maxr[i][j - 1], maxr[i + (1 << (j - 1))][j - 1]);
}
inline pii qmin(int l, int r) {
    int k = std::__lg(r - l + 1);
    return std::min(minl[l][k], minl[r - (1 << k) + 1][k]);
}
inline pii qmax(int l, int r) {
    int k = std::__lg(r - l + 1);
    return std::max(maxr[l][k], maxr[r - (1 << k) + 1][k]);
}

inline void work() {
    rmq_init();
    for (int i = 1; i <= n; ++i) {
        int pl = std::lower_bound(a + 1, a + n + 1, a[i] - r[i]) - a,
            pr = std::upper_bound(a + 1, a + n + 1, a[i] + r[i]) - a - 1;
        addedge(i, qmin(pl, pr).se);
        addedge(i, qmax(pl, pr).se);
    }
    tarjan();
    for (int i = 1; i <= sccno; ++i) {
        int len = v[i].size();
        for (int j = 0; j < len; ++j) {
            int x = v[i][j];
            for fec(iii, x, y) smin(dpl[i], dpl[scc[y]]), smax(dpr[i], dpr[scc[y]]), assert(scc[y] <= i);
        }
    }
    ll ans = 0;
    for (int i = 1; i <= n; ++i) {
        int pl = std::lower_bound(a + 1, a + n + 1, dpl[scc[i]]) - a,
            pr = std::upper_bound(a + 1, a + n + 1, dpr[scc[i]]) - a - 1;
        ans += (ll)i * (pr - pl + 1);
    }
    printf("%lld\n", ans % P);
}

inline void init() {
    read(n);
    for (int i = 1; i <= n; ++i) read(a[i]), read(r[i]);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj5017.html