可持久化数据结构【可持久化线段树(主席树)】相关

可持久化线段树(主席树)

#include<stdio.h>
#define MAXN 100001

using namespace std;

int sum[MAXN*20],lson[MAXN*20],rson[MAXN*20];
int a[MAXN],root[MAXN];
int n,m,tot,now;

int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

void maketree(int &t,int l,int r)
{
    t=++tot;
    if (l==r)
    {
        sum[t]=read();
        return;
    }
    int mid=(l+r)/2;
    maketree(lson[t],l,mid);
    maketree(rson[t],mid+1,r);
    sum[t]=sum[lson[t]]+sum[rson[t]];
}

void change(int old,int &t,int l,int r,int x,int y)//x点加上z
{
    t=++tot;
    lson[t]=lson[old],rson[t]=rson[old];
    sum[t]=sum[old]+y;
    if (l==r)return;

    int mid=(l+r)/2;
    if (x<=mid)change(lson[t],lson[t],l,mid,x,y);
    else change(rson[t],rson[t],mid+1,r,x,y);
}

int query(int t,int l,int r,int x,int y)//查询x~y区间和
{
    if (x<=l && r<=y)return sum[t];
    int mid=(l+r)/2,ans=0;
    if (x<=mid)ans+=query(lson[t],l,mid,x,y);
    if (y>mid)ans+=query(rson[t],mid+1,r,x,y);
    return ans;
}

int main()
{
    freopen("readin.txt","r",stdin);
    n=read();
    root[0]=1;
    maketree(root[0],1,n);
    m=read();
    while (m--)
    {
        int w=read(),x=read(),y=read();
        if (w==1)//第x点加y
        {
            now++;
            change(root[now-1],root[now],1,n,x,y);
        } 
        else//询问第x次修改后y~z区间和
        {
            int z=read();
            printf("%d\n",query(root[x],1,n,y,z));
        }
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/enjoy_pascal/article/details/80496390