线段树模板

模板(重载运算符部分需要结合具体题目)

const int N = $$;
template <class info> struct SegmentTree
{
    int n;
    vector<info> val;
    SegmentTree(int n_)
    {
        n = n_;
        val.resize(n << 2);
    }
    SegmentTree(int n_, vector<info> &a)
    {
        n = n_;
        val.resize(n << 2);
        function<void(int, int, int)> build = [&](int now, int l, int r) {
            if (l == r)
            {
                val[now] = a[l];
                return;
            }
            int mid = l + (r - l) / 2;
            build(now << 1, l, mid);
            build(now << 1 | 1, mid + 1, r);
            pushup(now);
        };
        build(1, 1, n);
    }
    void pushup(int now)
    {
        val[now] = val[now << 1] + val[now << 1 | 1];
    }
    void update(int now, int l, int r, int pos, const info &v)
    {
        if (l == r)
        {
            val[now] = v;
            return;
        }
        int mid = l + (r - l) / 2;
        if (pos <= mid)
        {
            update(now << 1, l, mid, pos, v);
        }
        else
        {
            update(now << 1 | 1, mid + 1, r, pos, v);
        }
        pushup(now);
    }
    info query(int now, int l, int r, int L, int R)
    {
        if (l > R || r < L)
        {
            return info();
        }
        if (l >= L && r <= R)
        {
            return val[now];
        }
        int mid = l + (r - l) / 2;
        return query(now << 1, l, mid, L, R) + query(now << 1 | 1, mid + 1, r, L, R);
    }
    template <class T> int findfirst(int now, int l, int r, T func)
    {
        if (!func(val[now]))
        {
            return -1;
        }
        if (l == r)
        {
            return l;
        }
        int mid = l + (r - l) / 2;
        int ret = findfirst(now << 1, l, mid, func);
        if (ret == -1)
        {
            ret = findfirst(now << 1 | 1, mid + 1, r, func);
        }
        return ret;
    }
    template <class T> int findlast(int now, int l, int r, T func)
    {
        if (!func(val[now]))
        {
            return -1;
        }
        if (l == r)
        {
            return l;
        }
        int mid = l + (r - l) / 2;
        int ret = findlast(now << 1 | 1, mid + 1, r, func);
        if (ret == -1)
        {
            ret = findlast(now << 1, l, mid, func);
        }
        return ret;
    }
};
struct info
{
    int x = 0;
};
SegmentTree<info> seg(N);
info operator+(const info &a, const info &b)
{
    info ret;
    ret.x = max(a.x, b.x);
    return ret;
}

例题

code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// #define int ll
const int N = 2E6 + 5;
template <class info> struct SegmentTree
{
    int n;
    vector<info> val;
    SegmentTree(int n_)
    {
        n = n_;
        val.resize(n << 2);
    }
    SegmentTree(int n_, vector<info> &a)
    {
        n = n_;
        val.resize(n << 2);
        function<void(int, int, int)> build = [&](int now, int l, int r) {
            if (l == r)
            {
                val[now] = a[l];
                return;
            }
            int mid = l + (r - l) / 2;
            build(now << 1, l, mid);
            build(now << 1 | 1, mid + 1, r);
            pushup(now);
        };
        build(1, 1, n);
    }
    void pushup(int now)
    {
        val[now] = val[now << 1] + val[now << 1 | 1];
    }
    void update(int now, int l, int r, int pos, const info &v)
    {
        if (l == r)
        {
            val[now] = v;
            return;
        }
        int mid = l + (r - l) / 2;
        if (pos <= mid)
        {
            update(now << 1, l, mid, pos, v);
        }
        else
        {
            update(now << 1 | 1, mid + 1, r, pos, v);
        }
        pushup(now);
    }
    info query(int now, int l, int r, int L, int R)
    {
        if (l > R || r < L)
        {
            return info();
        }
        if (l >= L && r <= R)
        {
            return val[now];
        }
        int mid = l + (r - l) / 2;
        return query(now << 1, l, mid, L, R) + query(now << 1 | 1, mid + 1, r, L, R);
    }
    template <class T> int findfirst(int now, int l, int r, T func)
    {
        if (!func(val[now]))
        {
            return -1;
        }
        if (l == r)
        {
            return l;
        }
        int mid = l + (r - l) / 2;
        int ret = findfirst(now << 1, l, mid, func);
        if (ret == -1)
        {
            ret = findfirst(now << 1 | 1, mid + 1, r, func);
        }
        return ret;
    }
    template <class T> int findlast(int now, int l, int r, T func)
    {
        if (!func(val[now]))
        {
            return -1;
        }
        if (l == r)
        {
            return l;
        }
        int mid = l + (r - l) / 2;
        int ret = findlast(now << 1 | 1, mid + 1, r, func);
        if (ret == -1)
        {
            ret = findlast(now << 1, l, mid, func);
        }
        return ret;
    }
};
struct info
{
    int x = 0;
};
SegmentTree<info> seg(N);
info operator+(const info &a, const info &b)
{
    info ret;
    ret.x = max(a.x, b.x);
    return ret;
}
void solve()
{
    int n;
    cin >> n;
    set<int> s{0, 2 * N};
    seg.update(1, 1, N, 1, {2 * N - 1});
    auto ins = [&](int x) {
        auto it = s.insert(x).first;
        int l = *prev(it);
        int r = *next(it);
        seg.update(1, 1, N, l + 1, {x - l - 1});
        seg.update(1, 1, N, x + 1, {r - x - 1});
    };
    auto del = [&](int x) {
        auto it = s.find(x);
        int l = *prev(it);
        int r = *next(it);
        seg.update(1, 1, N, l + 1, {r - l - 1});
        seg.update(1, 1, N, x + 1, {});
        s.erase(x);
    };
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        ins(x);
    }
    int q;
    cin >> q;
    for (int i = 1; i <= q; i++)
    {
        char op;
        int x;
        cin >> op >> x;
        if (op == '+')
        {
            ins(x);
        }
        else if (op == '-')
        {
            del(x);
        }
        else
        {
            int ans = seg.findfirst(1, 1, N, [&](info &a) { return a.x >= x; });
            cout << ans << " ";
        }
    }
    for (auto x : s)
    {
        seg.update(1, 1, N, x + 1, {});
    }
    cout << "\n";
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值