Special Topic: segment tree

Do not play too long segment tree hand has been born

Problem A: highway

False desired title, apparently denominator \ (R & lt C_ {-}. 1 + L ^ 2 \) . The all sub-segments within the interval and the seeking out everything is.

Then consider the tree line interval merger, it can not seem to do it.

Then SX Red Sun Guo enlighten me, we can take the idea of ​​a tree similar to stained, consider each edge can be after a few.

This is evident when comparing, for the \ ((R - i + 1 ) (i - L + 1) \) then the molecules is. \ (\ SUM \ _ Limits} {I = L ^ R & lt (R & lt - + I. 1) (I -. 1 + L) W_i \) .

Simplification is about \ (\ SUM \ _ Limits} {I = L ^ R & lt (R & lt -. 1 + L - the LR) W_i + (L + R & lt) W_i I - I 2 W_i ^ \) .

Note 3 segment tree Tag: \ (= W_i S_1, S_2 I = W_i, W_i S_3 = I ^ 2 \) .

Interval incorporated directly together.

Then consider modifying the right side, it is to add a \ (V (R & lt -. 1 + L - the LR) \) \ (V (L + R & lt) \ I SUM \) and $ -vi ^ 2 $.

再记\(s_4 = \sum i, s_5 = \sum i^2\).

This question would be finished.

Note pit:

  1. To that point, we maintain that line, we need to deal with it
  2. Able to open to open long long long long! ! Do not hesitate! ! If you WA20, and that is about to open long long did not open
#include <bits/stdc++.h>
#define ll long long

const int N = 100000 + 233;
ll n, m, sum[5]; char opt[5];
struct SegTree { ll l, r, s[8], tag; } t[N << 2];

inline void Pushup(ll p) {
    for (int i = 1; i <= 3; i++)
        t[p].s[i] = t[p << 1].s[i] + t[p << 1 | 1].s[i];
}

ll gcd(ll x, ll y) {
    return y == 0 ? x : gcd(y, x % y);
}

void Build(ll p, ll l, ll r) {
    t[p].l = l, t[p].r = r;
    if (l == r) return (void) (t[p].s[4] = l, t[p].s[5] = l * l);
    ll mid = (l + r) >> 1;
    Build(p << 1, l, mid), Build(p << 1 | 1, mid + 1, r);
    for (int i = 4; i <= 5; i++)
        t[p].s[i] = t[p << 1].s[i] + t[p << 1 | 1].s[i];
}

inline void Add(ll p, ll k) {
    t[p].s[1] += (t[p].r - t[p].l + 1) * k;
    t[p].s[2] += k * t[p].s[4];
    t[p].s[3] += k * t[p].s[5];
    t[p].tag += k;
}

inline void Pushdown(ll p) {
    Add(p << 1, t[p].tag), Add(p << 1 | 1, t[p].tag);
    t[p].tag = 0;
}

void Change(ll p, ll l, ll r, ll v) {
    if (l <= t[p].l && r >= t[p].r) return (void) Add(p, v);
    ll mid = (t[p].l + t[p].r) >> 1;
    if (t[p].tag) Pushdown(p);
    if (l <= mid) Change(p << 1, l, r, v);
    if (r > mid) Change(p << 1 | 1, l, r, v);
    Pushup(p);
}

void Ask(ll p, ll l, ll r) {
    if (l <= t[p].l && r >= t[p].r) {
        for (int i = 1; i <= 3; i++)
            sum[i] += t[p].s[i];
        return;
    }
    ll mid = (t[p].l + t[p].r) >> 1;
    if (t[p].tag) Pushdown(p);
    if (l <= mid) Ask(p << 1, l, r);
    if (r > mid) Ask(p << 1 | 1, l, r);
}

inline void print(ll x, ll y) {
    ll g = gcd(x, y);
    printf("%lld/%lld\n", x / g, y / g);
}

signed main() {
    scanf("%lld%lld", &n, &m);
    Build(1, 1, n);
    for (ll i = 1, l, r; i <= m; i++) {
        ll v;
        scanf("%s%lld%lld", opt, &l, &r); r--;
        if (opt[0] == 'C') {
            scanf("%lld", &v), Change(1, l, r, v);
        } else {
            sum[1] = sum[2] = sum[3] = 0;
            Ask(1, l, r);
            ll a = (r - l + 1 - l * r) * sum[1] + (r + l) * sum[2] - sum[3];
            ll b = (r - l + 2) * (r - l + 1) / 2;
            print(a, b);
        }
    }
    return 0;
}

Problem D: Sorting

Fourth listening to this problem (

The first hearing in the death house Xing Zeyu speak SJZEZ

The second victory in SDFZ listen high cold pigeon pigeon talk

The third time in TYWZ really listening to Red Sun Ricardo -SX get together to speak

Fourth giant giant koala listen to talk in HZ

Real public issues (

The most important point of this question is to ask only one location, and the answer is clearly monotone, you get away with half

Sorting arrangement to grind Ji too, turn into 01 sequences, 0 represents less than, greater than or equal to 1, so that it can maintain a "sort" process with the segment tree.

However, this problem of data over the water, bucket row optimization God what could go (((

#include <bits/stdc++.h>

const int N = 100005 + 233;
int n, m, q, ans, a[N];
struct Command { int l, r, op; } cmd[N];
struct SegTree {
    int l, r, sum, tag;
    #define l(p) tree[p].l
    #define r(p) tree[p].r
    #define sum(p) tree[p].sum
    #define tag(p) tree[p].tag
    #define ls(p) p << 1
    #define rs(p) p << 1 | 1
} tree[N << 2];

inline int R() {
    int a = 0; char c = getchar();
    while (!isdigit(c)) c = getchar();
    while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
    return a;
}

void Build(int p, int l, int r, int v) {
    l(p) = l, r(p) = r, tag(p) = -1;
    if (l == r) return (void) (sum(p) = a[l] >= v);
    int mid = (l + r) >> 1;
    Build(ls(p), l, mid, v), Build(rs(p), mid + 1, r, v);
    sum(p) = sum(ls(p)) + sum(rs(p));
}

void Pushdown(int p) {
    if (tag(p) != -1) {
        sum(ls(p)) = (r(ls(p)) - l(ls(p)) + 1) * tag(p);
        sum(rs(p)) = (r(rs(p)) - l(rs(p)) + 1) * tag(p);
        tag(ls(p)) = tag(rs(p)) = tag(p);
        tag(p) = -1;
    }
}

void Change(int p, int l, int r, int v) {
    if (l <= l(p) && r >= r(p)) {
        sum(p) = (r(p) - l(p) + 1) * v;
        tag(p) = v;
    } else {
        Pushdown(p);
        int mid = (l(p) + r(p)) >> 1;
        if (l <= mid) Change(ls(p), l, r, v);
        if (r > mid) Change(rs(p), l, r, v);
        sum(p) = sum(ls(p)) + sum(rs(p));
    }
}

int Query(int p, int l, int r) {
    if (l <= l(p) && r >= r(p)) 
        return sum(p);
    Pushdown(p);
    int mid = (l(p) + r(p)) >> 1, ret = 0;
    if (l <= mid) ret += Query(ls(p), l, r);
    if (r > mid) ret += Query(rs(p), l, r);
    return ret;
}

bool Check(int x) {
    Build(1, 1, n, x);
    for (int i = 1; i <= m; i++) {
        int cnt = Query(1, cmd[i].l, cmd[i].r);
        if (cnt != 0 && cnt != cmd[i].r - cmd[i].l + 1) {
            if (cmd[i].op) {
                Change(1, cmd[i].l, cmd[i].l + cnt - 1, 1);
                Change(1, cmd[i].l + cnt, cmd[i].r, 0);
            } else {
                Change(1, cmd[i].l, cmd[i].r - cnt, 0);
                Change(1, cmd[i].r - cnt + 1, cmd[i].r, 1);
            }
        }
    }
    return Query(1, q, q);
}

signed main() {
    n = R(), m = R();
    for (int i = 1; i <= n; i++)
        a[i] = R();
    for (int i = 1; i <= m; i++)
        cmd[i].op = R(), cmd[i].l = R(), cmd[i].r = R();
    q = R();
    int l = 1, r = n, mid;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (Check(mid)) {
            ans = mid;
            l = mid + 1;
        } else r = mid - 1;
    }
    return !printf("%d\n", ans);
}

Guess you like

Origin www.cnblogs.com/gekoo/p/11240280.html