ABC F 求调
  • 板块学术版
  • 楼主1234567890sjx
  • 当前回复0
  • 已保存回复1
  • 发布时间2024/6/1 21:40
  • 上次更新2024/6/2 07:44:39
查看原帖
ABC F 求调
1013955
1234567890sjx楼主2024/6/1 21:40

rt,马蜂良好。

#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;i++)
#define G(i,x,y) for(int i=x;i>=y;i--)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#define inf (7611257611378358090ll/2)
using namespace std;
const int N = 3050010, mod = 998244353;
struct Syx {
    int o, x;
} query[N];
int back[N];
int l[N], r[N];
// l[i] 表示 i 左边的这个数,如果是 -1 则不存在 r[i] 同理
int lll[N], rrr[N];
// lll[i] 表示 i 最大情况下左边的数 rrr[i] 同理
struct Node {
    int l, r, val, tag;
    void init(int p) {
        l = r = p;
        val = p;
        tag = 0;
    }
    void color(int v) {
        val = tag = v;
    }
};
namespace Sgt1 {

Node z[N << 2];
Node operator+(const Node &l, const Node &r) {
    return {l.l, r.r, l.val + r.val, 0ll};
}
void build(int l, int r, int rt) {
    if (l == r) return z[rt].init(l);
    int mid = l + r >> 1;
    build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
    z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
void pu(int rt) {
    if (z[rt].tag) {
        z[rt << 1].color(z[rt].tag);
        z[rt << 1 | 1].color(z[rt].tag);
        z[rt].tag = 0;
    }
}
void modify(int l, int r, int rt, int ll, int rr, int v) {
    if (ll <= l && r <= rr) {
        return z[rt].color(v);
    }
    pu(rt);
    int mid = l + r >> 1;
    if (ll <= mid) modify(l, mid, rt << 1, ll, rr, v);
    if (mid < rr) modify(mid + 1, r, rt << 1 | 1, ll, rr, v);
    z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
int query(int l, int r, int rt, int ll, int rr) {
    if (ll <= l && r <= rr) return z[rt].val;
    int mid = l + r >> 1; pu(rt); int s = 0;
    if (ll <= mid) s += query(l, mid, rt << 1, ll, rr);
    if (mid < rr) s += query(mid + 1, r, rt << 1 | 1, ll, rr);
    return s;
}
}
namespace Sgt2 {

Node z[N << 2];
Node operator+(const Node &l, const Node &r) {
    return {l.l, r.r, l.val + r.val, 0ll};
}
void build(int l, int r, int rt) {
    if (l == r) return z[rt].init(l);
    int mid = l + r >> 1;
    build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
    z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
void pu(int rt) {
    if (z[rt].tag) {
        z[rt << 1].color(z[rt].tag);
        z[rt << 1 | 1].color(z[rt].tag);
        z[rt].tag = 0;
    }
}
void modify(int l, int r, int rt, int ll, int rr, int v) {
    if (ll <= l && r <= rr) {
        return z[rt].color(v);
    }
    pu(rt);
    int mid = l + r >> 1;
    if (ll <= mid) modify(l, mid, rt << 1, ll, rr, v);
    if (mid < rr) modify(mid + 1, r, rt << 1 | 1, ll, rr, v);
    z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
int query(int l, int r, int rt, int ll, int rr) {
    if (ll <= l && r <= rr) return z[rt].val;
    int mid = l + r >> 1; pu(rt); int s = 0;
    if (ll <= mid) s += query(l, mid, rt << 1, ll, rr);
    if (mid < rr) s += query(mid + 1, r, rt << 1 | 1, ll, rr);
    return s;
}
}
auto main() [[O3]] -> signed {
    int q, k;
    cin >> q >> k;
    F(i, 1, q) {
        cin >> query[i].o >> query[i].x;
    }
    set<int> se;
    F(i, 1, q) {
        se.insert(query[i].x);
    }
    map<int, int> mp;
    int idx = 0;
    for (auto &x : se) {
        mp[x] = ++idx;
        back[idx] = x;
    }
    F(i, 1, q) {
        query[i].x = mp[query[i].x];
    }
    memset(l, -1, sizeof l);
    memset(r, -1, sizeof r);
    memset(lll, -1, sizeof lll);
    memset(rrr, -1, sizeof rrr);
    Sgt1::build(1, idx, 1);
    Sgt2::build(1, idx, 1);
    // Sgt1 维护每一个点最左边能到哪里
    // Sgt2 维护每一个点最右边能到哪里
    set<int> inset;
    F(i, 1, q) {
        if (query[i].o == 1) {
            if (!inset.count(query[i].x)) {
                int real = back[query[i].x];
                inset.insert(query[i].x);
                auto it = inset.lower_bound(query[i].x);
                if (it != inset.begin()) {
                    it--;
                    rrr[*it] = query[i].x;
                    lll[query[i].x] = *it;
                    it++;
                }
                if (it != --inset.end()) {
                    it++;
                    lll[*it] = query[i].x;
                    rrr[query[i].x] = *it;
                    it--;
                }
                if (lll[query[i].x] != -1 && abs(real - back[lll[query[i].x]]) <= k) {
                    if (rrr[query[i].x] != -1 && abs(real - back[rrr[query[i].x]]) <= k) {
                        int Right = Sgt2::query(1, idx, 1, rrr[query[i].x], rrr[query[i].x]);
                        int Left = Sgt2::query(1, idx, 1, lll[query[i].x], lll[query[i].x]);
                        Sgt1::modify(1, idx, 1, Left, Right, Left);
                        Sgt2::modify(1, idx, 1, Left, Right, Right);
                    } else {
                        int Right = real;
                        int Left = Sgt2::query(1, idx, 1, lll[query[i].x], lll[query[i].x]);
                        Sgt1::modify(1, idx, 1, Left, Right, Left);
                        Sgt2::modify(1, idx, 1, Left, Right, Right);
                    }
                } else if (rrr[query[i].x] != -1 && abs(real - back[rrr[query[i].x]]) <= k) {
                    int Right = Sgt2::query(1, idx, 1, rrr[query[i].x], rrr[query[i].x]);
                    int Left = real;
                    Sgt1::modify(1, idx, 1, Left, Right, Left);
                    Sgt2::modify(1, idx, 1, Left, Right, Right);
                }
            } else {
                int real = back[query[i].x];
                auto it = inset.lower_bound(query[i].x);
                if (lll[query[i].x] != -1 && rrr[query[i].x] != -1 && abs(back[rrr[query[i].x]] - back[lll[query[i].x]]) > k) {
                    int Right = Sgt2::query(1, idx, 1, query[i].x, query[i].x);
                    Sgt1::modify(1, idx, 1, rrr[query[i].x], Right, rrr[query[i].x]);
                    int Left = Sgt1::query(1, idx, 1, query[i].x, query[i].x);
                    Sgt2::modify(1, idx, 1, Left, lll[query[i].x], lll[query[i].x]);
                    lll[rrr[query[i].x]] = rrr[lll[query[i].x]] = -1;
                } else if (lll[query[i].x] != -1 && rrr[query[i].x] != -1) {
                    lll[rrr[query[i].x]] = rrr[query[i].x];
                    rrr[lll[query[i].x]] = lll[query[i].x];
                }
                else if (lll[query[i].x] != -1) rrr[lll[query[i].x]] = -1;
                else if (rrr[query[i].x] != -1) lll[rrr[query[i].x]] = -1;
                inset.erase(query[i].x);
            }
        } else {
            int Left = Sgt1::query(1, idx, 1, query[i].x, query[i].x);
            int Right = Sgt2::query(1, idx, 1, query[i].x, query[i].x);
            cout << Right - Left + 1 << '\n';
        }
    }
}
2024/6/1 21:40
加载中...