ZOJ2112 Dynamic Rankings(树套树:树状数组套主席树)

树状维护区间,内部主席树(动态开点)维护值域;

树状数组的结点i代表第i个版本的权值线段树并且其是建立在原区间 [ i - lowbit(i) + 1 , i ] ;

通过树状数组对结点(每个节点都是一个线段树)求和,就能得到一个完整版本的主席树;

由于树状数组的特殊性,这里不需要保存历史版本,直接通过树状向上更新即可;

我的代码是递归的写法,有点耗内存

^(* ̄(oo) ̄)^ ZOJ上死活过不了,不是段错误就是超内存,这32M内存做主席树的题真的是一把辛酸泪,但是洛谷过了,先挂洛谷的递归AC代码;

用循环搞搞ZOJ压压内存,等过了,再贴份代码吧。

#include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const int N=6e4+5;
const int M=1e4+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-9;
const long double pi=acos(-1.0L);
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
    LL x=0,t=1;
    char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    return x*t;
}
struct node{ int l,r,v; }c[40*N];
int root[N],t[N+M],a[N],L[M],R[M],K[M],cmd[M],len,tot,n,m,cnt;
int qx[N],qy[N],tx,ty;
void update(int l,int r,int &now,int pos,int d)
{
    if(now==0) now=++cnt;
    c[now].v+=d;
    if(l==r) return ;
    int mid=l+r>>1;
    if(pos<=mid) update(l,mid,c[now].l,pos,d);
    else update(mid+1,r,c[now].r,pos,d);
}
inline int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y)
{
    for(int i=x;i<=n;i+=lowbit(i)) update(1,len,root[i],a[x],y);
}
int query(int l,int r,int k)
{
    if(l==r) return l;
    int mid=l+r>>1;
    int sum=0;
    for(int i=1;i<=ty;i++) sum+=c[c[qy[i]].l].v;
    for(int i=1;i<=tx;i++) sum-=c[c[qx[i]].l].v;
    if(k<=sum)
    {
        for(int i=1;i<=ty;i++) qy[i]=c[qy[i]].l;
        for(int i=1;i<=tx;i++) qx[i]=c[qx[i]].l;
        return query(l,mid,k);
    }
    else
    {
        for(int i=1;i<=ty;i++) qy[i]=c[qy[i]].r;
        for(int i=1;i<=tx;i++) qx[i]=c[qx[i]].r;
        return query(mid+1,r,k-sum);
    }
}
int main()
{
    int T=1;
    while(T--)
    {
        for(int i=1;i<=cnt;i++) root[i]=c[i].l=c[i].r=c[i].v=0;
        cnt=tx=ty=0;
        tot=n=read(),m=read();
        for(int i=1;i<=n;i++) t[i]=a[i]=read();
        for(int i=1;i<=m;i++)
        {
            char ch[2];
            int x,y,z;
            scanf("%s",ch);
            cmd[i]=ch[0];
            if(ch[0]=='Q') L[i]=read(),R[i]=read(),K[i]=read();
            else L[i]=read(),t[++tot]=R[i]=read();
        }
        sort(t+1,t+tot+1);
        len=unique(t+1,t+tot+1)-t-1;
        //for(int i=1;i<=len;i++) printf("%d%c",t[i],i==len?'\n':' ');
        for(int i=1;i<=n;i++) a[i]=lower_bound(t+1,t+len+1,a[i])-t;
        for(int i=1;i<=n;i++) add(i,1);
        for(int i=1;i<=m;i++)
        {
            if(cmd[i]=='Q')
            {
                tx=ty=0;
                for(int j=L[i]-1;j;j-=lowbit(j)) qx[++tx]=root[j];
                for(int j=R[i];j;j-=lowbit(j)) qy[++ty]=root[j];
                printf("%d\n",t[query(1,len,K[i])]);
            }
            else
            {
                add(L[i],-1);
                a[L[i]]=lower_bound(t+1,t+len+1,R[i])-t;
                add(L[i],1);
            }
        }
    }
    return 0;
}
递归版本(洛谷)

猜你喜欢

转载自www.cnblogs.com/DeepJay/p/12404840.html