"APIO 2019" street

topic

Obviously a skilled player should be able to see at a glance the answer we need to maintain the point

Apparently only occur when you disconnect or connect on a certain point on the edge of the left and right sides Unicom's contribution, this take \ (set \) maintain just fine

That question now is how to maintain the

Consider a very \ (sb \) of the problem, we just want to know a point \ ((x, y) \ ) from the start to a time \ (t \) How much time is Unicom

If \ (i \) time \ ((x, y) \) suddenly Unicom, and then we'll answer plus \ (t-i + 1 \) , if \ (i \) time \ ((x, y ) \) suddenly drops out, we'll answer minus \ (t-i + 1 \) , apparently correctness

So we just need to maintain those constants were added and the number of the current time can answer questions any time of the

So the question becomes check matrix and single point, clearly the problem into a three-dimensional partial order may then be differential, directly vigorously \ (The cdq \) , of course, also be set directly on the tree Tree

Code

#include <bits/stdc++.h>
#define L first
#define R second
#define re register
#define LL long long
#define lb(x) ((x) & (-x))
#define mp std::make_pair
#define set_it std::set<pii>::iterator
inline int read() {
    char c = getchar();
    int x = 0;
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - 48, c = getchar();
    return x;
}
typedef std::pair<int, int> pii;
const int maxn = 3e5 + 5;
const int M = maxn * 200;
std::set<pii> s;
int n, m, B, cnt;
char S[maxn], op[12];
int rt[maxn << 2];
LL g[M], A;
int h[M], l[M], r[M];
int ins(int now, int x, int y, int pos, int v, int w) {
    if (!now)
        now = ++cnt;
    if (x == y) {
        g[now] += v, h[now] += w;
        return now;
    }
    int mid = x + y >> 1;
    if (pos <= mid)
        l[now] = ins(l[now], x, mid, pos, v, w);
    else
        r[now] = ins(r[now], mid + 1, y, pos, v, w);
    g[now] = g[l[now]] + g[r[now]];
    h[now] = h[l[now]] + h[r[now]];
    return now;
}
void find(int now, int x, int y, int pos) {
    if (!now)
        return;
    if (x == y) {
        A += g[now];
        B += h[now];
        return;
    }
    int mid = x + y >> 1;
    if (pos <= mid)
        find(l[now], x, mid, pos);
    else
        find(r[now], mid + 1, y, pos), A += g[l[now]], B += h[l[now]];
}
void change(int x, int y, int a, int b) {
    if (y > n)
        return;
    for (re int i = x; i <= n; i += lb(i)) rt[i] = ins(rt[i], 1, n, y, a, b);
}
void query(int x, int y) {
    for (re int i = x; i; i -= lb(i)) find(rt[i], 1, n, y);
}
inline pii ask(int pos) {
    s.insert(mp(pos, n + 1));
    set_it it = s.find(mp(pos, n + 1));
    --it;
    s.erase(mp(pos, n + 1));
    return *it;
}
inline void add(int x, int y, int lx, int ry, int t, int v) {
    change(x, lx, v * (1 - t), v);
    change(x, ry + 1, v * (t - 1), -1 * v);
    change(y + 1, lx, v * (t - 1), -1 * v);
    change(y + 1, ry + 1, v * (1 - t), v);
}
inline void getAns(int t) {
    int x = read(), y = read();
    if (x > y)
        std::swap(x, y);
    A = 0, B = 0;
    query(x, y);
    printf("%d\n", A + B * t);
}
int main() {
    n = read() + 1, m = read();
    scanf("%s", S + 1);
    for (re int i = 1; i < n; i++) S[i] -= '0';
    int t = 1;
    for (re int i = 1; i <= n; i++)
        if (!S[i])
            s.insert(mp(t, i)), t = i + 1;
    for (set_it it = s.begin(); it != s.end(); ++it) add((*it).L, (*it).R, (*it).L, (*it).R, 0, 1);
    for (re int i = 1; i <= m; i++) {
        scanf("%s", op);
        if (op[0] == 'q')
            getAns(i - 1);
        if (op[0] == 't') {
            int x = read();
            pii ll = ask(x), rr = ask(x + 1);
            if (!S[x]) {
                add(ll.L, ll.R, rr.L, rr.R, i, 1);
                s.erase(ll), s.erase(rr);
                s.insert(mp(ll.L, rr.R));
            } else {
                add(ll.L, x, x + 1, rr.R, i, -1);
                s.erase(ll);
                s.insert(mp(ll.L, x));
                s.insert(mp(x + 1, rr.R));
            }
            S[x] ^= 1;
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/asuldb/p/11098448.html