Dynamic Rankings ZOJ - 2112

点击打开链接

动态主席树模板 推荐博客点击打开链接

先用原序列的n个数建立一个静态主席树 再利用树状数组维护一个动态主席树 每次查询利用静态与动态之和 而更改只改动态主席树 即在取lowbit过程中把每个遍历到的位置对应的线段树更新一条链

虽说树状数组可以解决的问题线段树都能解决 但是在这里如果用线段树的话 本来就很高的时间空间复杂度会更加无法承受 并且代码量也会增大很多

#include <bits/stdc++.h>
using namespace std;

struct node1
{
    int tp;
    int l;
    int r;
    int k;
};

struct node2
{
    int nl;
    int nr;
    int val;
};

map <int,int> mp;
node1 pre[10010];
node2 tree[2400010];
int val1[60010],val2[60010],root[60010],groot[60010],use[60010];
int n,q,num,len;

int lowbit(int cur)
{
    return cur&(-cur);
}

int build(int l,int r)
{
    int cur,m;
    cur=num++;
    tree[cur].nl=0,tree[cur].nr=0,tree[cur].val=0;
    if(l==r) return cur;
    m=(l+r)/2;
    tree[cur].nl=build(l,m);
    tree[cur].nr=build(m+1,r);
    return cur;
}

int update(int rot,int tar,int val,int l,int r)
{
    int cur,m;
    cur=num++;
    tree[cur]=tree[rot];
    tree[cur].val+=val;
    if(l==r) return cur;
    m=(l+r)/2;
    if(tar<=m) tree[cur].nl=update(tree[rot].nl,tar,val,l,m);
    else tree[cur].nr=update(tree[rot].nr,tar,val,m+1,r);
    return cur;
}

int getsum(int cur)
{
    int res;
    res=0;
    while(cur>0)
    {
        res+=tree[tree[use[cur]].nl].val;
        cur-=lowbit(cur);
    }
    return res;
}

void solve(int cur,int tar,int val)
{
    while(cur<=n)
    {
        groot[cur]=update(groot[cur],tar,val,1,len);
        cur+=lowbit(cur);
    }
}

int query(int pl,int pr,int lrot,int rrot,int k,int l,int r)
{
    int sum,m,i;
    if(l==r) return l;
    sum=(getsum(pr)-getsum(pl-1))+(tree[tree[rrot].nl].val-tree[tree[lrot].nl].val);
    m=(l+r)/2;
    if(sum>=k)
    {
        for(i=pl-1;i>0;i-=lowbit(i)) use[i]=tree[use[i]].nl;
        for(i=pr;i>0;i-=lowbit(i)) use[i]=tree[use[i]].nl;
        return query(pl,pr,tree[lrot].nl,tree[rrot].nl,k,l,m);
    }
    else
    {
        for(i=pl-1;i>0;i-=lowbit(i)) use[i]=tree[use[i]].nr;
        for(i=pr;i>0;i-=lowbit(i)) use[i]=tree[use[i]].nr;
        return query(pl,pr,tree[lrot].nr,tree[rrot].nr,k-sum,m+1,r);
    }
}

int main()
{
    int t,i,j,p;
    char op[10];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&q);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&val1[i]);
            val2[i]=val1[i];
        }
        len=n;
        for(i=1;i<=q;i++)
        {
            scanf("%s",op);
            if(op[0]=='Q')
            {
                pre[i].tp=0;
                scanf("%d%d%d",&pre[i].l,&pre[i].r,&pre[i].k);
            }
            else
            {
                pre[i].tp=1;
                scanf("%d%d",&pre[i].l,&pre[i].r);
                val2[++len]=pre[i].r;
            }
        }
        sort(val2+1,val2+len+1);
        len=unique(val2+1,val2+len+1)-val2-1;
        mp.clear();
        for(i=1;i<=len;i++)
        {
            mp[val2[i]]=i;
        }
        num=0;
        root[0]=build(1,len);
        for(i=1;i<=n;i++)
        {
            root[i]=update(root[i-1],mp[val1[i]],1,1,len);
        }
        for(i=1;i<=n;i++) groot[i]=root[0];
        for(i=1;i<=q;i++)
        {
            if(pre[i].tp==0)
            {
                for(j=pre[i].l-1;j>0;j-=lowbit(j)) use[j]=groot[j];
                for(j=pre[i].r;j>0;j-=lowbit(j)) use[j]=groot[j];
                p=query(pre[i].l,pre[i].r,root[pre[i].l-1],root[pre[i].r],pre[i].k,1,len);
                printf("%d\n",val2[p]);
            }
            else
            {
                solve(pre[i].l,mp[val1[pre[i].l]],-1);
                solve(pre[i].l,mp[pre[i].r],1);
                val1[pre[i].l]=pre[i].r;
            }
        }
    }
    return 0;
}

阅读更多
文章标签: 动态主席树 ZOJ
个人分类: 数据结构
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Dynamic Rankings ZOJ - 2112

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭