【代码】洛谷P3380 二逼平衡树

题目链接

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <cmath>
#define pk putchar(' ')
#define ph puts("")
typedef long long ll;
const int N = 1e5 + 5, INF = (1ll << 31) - 1;
using namespace std;
int n, m, a[N];
int rt[N], cnt, tmp[N], tot, t1[N], t2[N], tot1, tot2;
struct node 
{
    int ls, rs, sum;
} t[N << 7];
struct ques 
{
    int l, r, val, Or;
} as[N];
int lowbit(int x) 
{ 
	return x & -x; 
}
void modify(int &now, int l, int r, int pos, int val) 
{
    if (!now)
        now = ++cnt;
    if (l == r) {
        t[now].sum += val;
        return;
    }
    int Mid = (l + r) >> 1;
    if (pos <= Mid)
        modify(t[now].ls, l, Mid, pos, val);
    else
        modify(t[now].rs, Mid + 1, r, pos, val);
    t[now].sum = t[t[now].ls].sum + t[t[now].rs].sum;
}
void premodify(int pos, int val) 
{
    for (int i = pos; i <= n; i += lowbit(i)) modify(rt[i], 1, tot, a[pos], val);
}
int query(int x, int l, int r, int k) 
{
    if (l == r)
        return t[x].sum;
    int Mid = (l + r) >> 1;
    if (k <= Mid)
        return query(t[x].ls, l, Mid, k);
    else
        return t[t[x].ls].sum + query(t[x].rs, Mid + 1, r, k);
}
int get_rank(int l, int r, int k) 
{
    int res = 0;
    l--;
    for (int i = r; i > 0; i -= lowbit(i)) 
		res += query(rt[i], 1, tot, k);
    for (int i = l; i > 0; i -= lowbit(i)) 
		res -= query(rt[i], 1, tot, k);
    return res;
}
int xth(int l, int r, int k) 
{
    int Mid = (l + r) >> 1;
    if (l == r)
        return Mid;
    int res = 0;
    for (int i = 1; i <= tot1; i++) res += t[t[t1[i]].ls].sum;
    for (int i = 1; i <= tot2; i++) res -= t[t[t2[i]].ls].sum;
    if (res >= k) 
	{
        for (int i = 1; i <= tot1; i++) t1[i] = t[t1[i]].ls;
        for (int i = 1; i <= tot2; i++) t2[i] = t[t2[i]].ls;
        return xth(l, Mid, k);
    } 
	else 
	{
        for (int i = 1; i <= tot1; i++) t1[i] = t[t1[i]].rs;
        for (int i = 1; i <= tot2; i++) t2[i] = t[t2[i]].rs;
        return xth(Mid + 1, r, k - res);
    }
}
int get_xth(int l, int r, int k) 
{
    l--;
    tot1 = 0, tot2 = 0;
    for (int i = r; i > 0; i -= lowbit(i)) 
		t1[++tot1] = rt[i];
    for (int i = l; i > 0; i -= lowbit(i)) 
		t2[++tot2] = rt[i];
    return tmp[xth(1, tot, k)];
}
template <class T>
void rd(T &x)
{
    x = 0;
    int f = 1;
    char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    x *= f;
}
template <class T>
void pt(T x)
{
    if (x < 0)
        putchar('-'), x = (~x) + 1;
    if (x > 9)
        pt(x / 10);
    putchar(x % 10 ^ 48);
}
int main() 
{
	// freopen("testdata.in", "r", stdin);
	// freopen("test.out", "w", stdout);
    rd(n), rd(m);
    for (int i = 1; i <= n; i++) 
        rd(a[i]), tmp[i] = a[i];
    tot = n;
    for (int i = 1; i <= m; i++) 
	{
        rd(as[i].Or);
        switch (as[i].Or) 
		{
            case 3: 
			{
                rd(as[i].l);
                rd(as[i].val);
                tmp[++tot] = as[i].val;
                break;
            }
            default: 
			{
                rd(as[i].l);
                rd(as[i].r);
                rd(as[i].val);
                if (as[i].Or != 2)
                    tmp[++tot] = as[i].val;
                break;
            }
        }
    }
    sort(tmp + 1, tmp + 1 + tot);
    tot = unique(tmp + 1, tmp + 1 + tot) - tmp - 1;
    for (int i = 1; i <= n; i++) 
        a[i] = lower_bound(tmp + 1, tmp + 1 + tot, a[i]) - tmp, premodify(i, 1);
    for (int i = 1; i <= m; i++) 
        switch (as[i].Or) 
		{
            case 1: 
			{
                as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
                pt(get_rank(as[i].l, as[i].r, as[i].val - 1) + 1), ph;
                break;
            }
            case 2: 
			{
                pt(get_xth(as[i].l, as[i].r, as[i].val)), ph;
                break;
            }
            case 3:
			{
                premodify(as[i].l, -1);
                a[as[i].l] = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
                premodify(as[i].l, 1);
                break;
            }
            case 4: 
			{
                as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
                int pre = get_rank(as[i].l, as[i].r, as[i].val - 1);
                int ans = get_xth(as[i].l, as[i].r, pre);
                if (pre == 0)
                    pt(-INF), ph;
                else
                    pt(ans), ph;
                break;
            }
            default: 
			{
                as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
                int bac = get_rank(as[i].l, as[i].r, as[i].val);
                int ans = get_xth(as[i].l, as[i].r, bac + 1);
                if (bac == as[i].r - as[i].l + 1)
                    pt(INF), ph;
                else
                    pt(ans), ph;
                break;
            }
        }
    return 0;
}

Thanks!

原创文章 23 获赞 41 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43537070/article/details/103388111
今日推荐