Chairman of the tree - the dynamic range of small k

Chairman of the tree - the dynamic range of the \ (k \) small

Template title here in Los Valley 2617 .

First make a summary of a few questions:

Read this article requires a foundation Chairman tree, that is, by the interval kth template title.

Static Overall kth:

what sort of looking for small k, the time complexity \ (O (nlogn) \) .

Dynamic Overall kth:

Weight segment tree maintenance at the time complexity \ (O (nlogn) \) .

Static interval kth:

Chairman tree maintenance, time complexity \ (O (nlogn) \) .

Dynamic range kth:

This is the title.

Recall how the Chairman of the tree is still maintaining the kth interval.

After the establishment of sustainable tree line, using the kth thinking query interval and the prefix.

So we want to modify the operating range kth band, prefix and is the key.

We in the maintenance and general prefix, support query and modify operations, using what data structure?

  • Fenwick tree / tree line.

So this time we generally have a concept of dynamic Chairman and Chairman of the tree in the tree data structure on the already somewhat different.

  • Chairman dynamic tree: the tree cover tree .
  • Static Chairman tree: be persistent weight segment tree .

How sets are a problem, but simply think of can be found, we maintain a tree for each node array tree array (inner) layer to maintain weight segment tree (the root) , we can solve this problem .

  • Repair Operation:
    • If the position of a digital \ (a_i = x \) modified to \ (the y-\) , then on the outer Fenwick tree, we need to modify \ (logn \) nodes, and for each node (on behalf of a weight segment tree), respectively \ (logN \) nodes affected, so complexity is modified \ (O ((logN) ^ 2) \) .
  • Search operation:
    • For each \ ([L, R] \ ) queries between, let's extract this interval \ (logn \) a root node, and then converting the range of questions seeking to static Chairman tree \ (k \) small.
    • Time complexity is \ (O ((logN) ^ 2) \) .

Doing so the total time complexity in \ (O (n (logn) ^ 2) \) on.

Next solve some of the problem space.

We know the tree line space complexity is \ (O (4n) \) , that is, \ (O (the n-) \) , the complexity of Fenwick tree is \ (O (the n-) \) , then doing so space complexity reached \ (O (^ n-2) \) .

Think about how to optimize?

We just calculate the spatial complexity, to open up to each node based on the weight regarded complete segment tree.

We query / modify operation of the scale is \ ((logn) ^ 2 \ ) level.

That is not dynamically open points.

For us to access node to node creation, who can not have access to, and on the matter.

Attaching \ (luogu2617 \) code.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int n, m, a[maxn], b[maxn<<1], len;

struct Query
{
    int op;
    int i, j, k;
}q[maxn];

//1e5的log大概在20左右 20*20=400
int sum[maxn*400];
int ls[maxn*400];
int rs[maxn*400];
int rt[maxn*400];
int tot;

void update_SgT(int &rt, int l, int r, int x, int val)
{
    if(!rt) rt = ++tot;
    if(l == r)
    {
        sum[rt] += val;
        return;
    }
    int mid = (l+r) >> 1;
    if(x <= mid) update_SgT(ls[rt], l, mid, x, val);
    else update_SgT(rs[rt], mid+1, r, x, val);
    sum[rt] = sum[ls[rt]] + sum[rs[rt]];
}

inline int lowbit(int x){
    return x&(-x);
}

void update_BIT(int pos, int x, int val)
{
    for(int i = pos; i <= n; i += lowbit(i))
        update_SgT(rt[i], 1, len, x, val);
}

///提取区间线段树的根节点
int rt1[maxn], rt2[maxn], cnt1, cnt2;
void locate(int l, int r)
{
    cnt1 = cnt2 = 0;
    for(int i = l-1; i; i -= lowbit(i))
        rt1[++cnt1] = rt[i];
    for(int i = r; i; i -= lowbit(i))
        rt2[++cnt2] = rt[i];
}

int ask(int l, int r, int k)
{
    if(l == r) return l;
    int mid = (l+r) >> 1;
    int suml = 0;
    for(int i = 1; i <= cnt1; i++)
        suml -= sum[ls[rt1[i]]];
    for(int i = 1; i <= cnt2; i++)
        suml += sum[ls[rt2[i]]];
    if(suml >= k)
    {
        for(int i = 1; i <= cnt1; i++)
            rt1[i] = ls[rt1[i]];
        for(int i = 1; i <= cnt2; i++)
            rt2[i] = ls[rt2[i]];
        return ask(l, mid, k);
    }
    else
    {
        for(int i = 1; i <= cnt1; i++)
            rt1[i] = rs[rt1[i]];
        for(int i = 1; i <= cnt2; i++)
            rt2[i] = rs[rt2[i]];
        return ask(mid+1, r, k-suml);
    }

}


int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        b[++len] = a[i];
    }

    char op[2];
    for(int i = 1; i <= m; i++)
    {
        scanf("%s", op);
        if(op[0] == 'Q')
        {
            q[i].op = 0;
            scanf("%d%d%d", &q[i].i, &q[i].j, &q[i].k);
        }
        else
        {
            q[i].op = 1;
            scanf("%d%d", &q[i].i, &q[i].k);
            b[++len] = q[i].k;
        }
    }

    //数值离散化
    sort(b+1, b+1+len);
    len = unique(b+1, b+1+len)-b-1;
    for(int i = 1; i <= n; i++)
        a[i] = lower_bound(b+1, b+len+1, a[i])-b;
    for(int i = 1; i <= m; i++)
        if(q[i].op) q[i].k = lower_bound(b+1, b+len+1, q[i].k)-b;

    //建树(动态开点形式)
    for(int i = 1; i <= n; i++)
        update_BIT(i, a[i], 1);

    for(int i = 1; i <= m; i++)
    {
        if(q[i].op)
        {
            update_BIT(q[i].i, a[q[i].i], -1);
            a[q[i].i] = q[i].k;
            update_BIT(q[i].i, q[i].k, 1);
        }
        else
        {
            locate(q[i].i, q[i].j);
            int ans = b[ask(1, len, q[i].k)];
            printf("%d\n", ans);
        }
    }

    return 0;
}

Guess you like

Origin www.cnblogs.com/zxytxdy/p/12375599.html