zoukankan      html  css  js  c++  java
  • 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组

    【BZOJ1901】Zju2112 Dynamic Rankings

    Description

    给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 

    Input

    第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

    Output

    对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

    Sample Input

    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3

    Sample Output

    3
    6

    HINT

    20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

    题解:对于动态修改的问题,我们采用树状数组套主席树的做法(但还是离线)。什么叫树状数组套主席树呢?

    就是正常的主席树每棵线段树保存的是[1,i]这个区间,而这里的主席树相当于保存的相当于树状数组上[1,i-lowbit+1]+...+[1,i]这些线段树的和,所以我们在查询的时候就要同时在logn棵线段树上查询。那么在修改时我们每修改一个数,也要新建logn棵线段树。

    还有注意这题是a[i]可以等于0

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=20010;
    int n,m,tot,nm,ta,tb;
    struct NUM
    {
        int num,org;
    }v[maxn];
    struct NODE
    {
        int ls,rs,siz;
    }s[maxn*200];
    int qa[maxn],qb[maxn],qc[maxn],qk[maxn],ref[maxn],root[maxn];
    int now[maxn],pos[maxn],val[maxn],sa[maxn],sb[maxn];
    char str[5];
    bool cmp1(NUM a,NUM b)
    {
        return a.num<b.num;
    }int readin()
    {
        int ret=0,f=1;    char gc=getchar();
        while(gc<'0'||gc>'9'){if(gc=='-')f=-f;    gc=getchar();}
        while(gc>='0'&&gc<='9')    ret=ret*10+gc-'0',gc=getchar();
        return ret*f;
    }
    void insert(int x,int &y,int l,int r,int p,int q)
    {
        y=++tot;
        if(l==r)
        {
            s[y].siz=s[x].siz+q;
            return ;
        }
        int mid=l+r>>1;
        if(p<=mid)    s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,p,q);
        else    s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,p,q);
        s[y].siz=s[s[y].ls].siz+s[s[y].rs].siz;
    }
    int query(int l,int r,int p)
    {
        if(l==r)    return ref[l];
        int i,suma=0,sumb=0;
        int mid=l+r>>1;
        for(i=1;i<=ta;i++)    suma+=s[s[sa[i]].ls].siz;
        for(i=1;i<=tb;i++)    sumb+=s[s[sb[i]].ls].siz;
        if(sumb-suma>=p)
        {
            for(i=1;i<=ta;i++)    sa[i]=s[sa[i]].ls;
            for(i=1;i<=tb;i++)    sb[i]=s[sb[i]].ls;
            return query(l,mid,p);
        }
        else
        {
            for(i=1;i<=ta;i++)    sa[i]=s[sa[i]].rs;
            for(i=1;i<=tb;i++)    sb[i]=s[sb[i]].rs;
            return query(mid+1,r,p-sumb+suma);
        }
    }
    int main()
    {
        n=readin(),m=readin();
        int i,j,a,b,pre;
        for(i=1;i<=n;i++)    v[++nm].num=readin(),v[nm].org=nm;
        for(i=1;i<=m;i++)
        {
            scanf("%s",str);
            qa[i]=readin(),qb[i]=readin();
            if(str[0]=='Q')    qc[i]=readin();
            else    v[++nm].num=qb[i],v[nm].org=n+i,qk[i]=1;
        }
        sort(v+1,v+nm+1,cmp1);
        for(ref[pre=0]=-1,i=1;i<=nm;i++)
        {
            if(v[i].num>ref[pre])    ref[++pre]=v[i].num;
            if(v[i].org>n)    qb[v[i].org-n]=pre;
            else    val[v[i].org]=pre;
        }
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j+=j&-j)
                insert(root[j],root[j],1,nm,val[i],1);
        for(i=1;i<=m;i++)
        {
            if(qk[i]==1)
            {
                for(j=qa[i];j<=n;j+=j&-j)    insert(root[j],root[j],1,nm,val[qa[i]],-1);
                val[qa[i]]=qb[i];
                for(j=qa[i];j<=n;j+=j&-j)    insert(root[j],root[j],1,nm,qb[i],1);
            }
            else
            {
                for(ta=0,j=qa[i]-1;j;j-=j&-j)    sa[++ta]=root[j];
                for(tb=0,j=qb[i];j;j-=j&-j)    sb[++tb]=root[j];
                printf("%d
    ",query(1,nm,qc[i]));
            }
        }
    }
  • 相关阅读:
    PAT 甲级 1113 Integer Set Partition
    简单 dp
    #Leetcode# 707. Design Linked List
    #Leetcode# 817. Linked List Components
    #Leetcode# 268. Missing Number
    #Leetcode# 328. Odd Even Linked List
    #Leetcode# 445. Add Two Numbers II
    jzoj 1252. 天平
    2019.01.26【NOIP提高组】模拟 B 组 总结
    【NOIP2011DAY2】计算系数
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6292020.html
Copyright © 2011-2022 走看看