• bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希


    1901: Zju2112 Dynamic Rankings

    Time Limit: 10 Sec  Memory Limit: 128 MB

    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继续回答上面的问题。

    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
    m,n≤10000

    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

     如果查询第k大,我们直接用主席树就可以了,但是加上了修改操作,就需要再加上一维树状数组维护
    这样就在每个lowbit修改就能维护出所有信息,查询同理。时间复杂度O(nlog2n)
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define inf 1000000007
    #define ll long long
    #define M 10000010
    #define N 10010
    inline int rd()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,v[N],A[N],B[N],K[N];
    int hs[N<<1],ji[N<<1],tt,tot=1;
    int rt[N],sz[M],ls[M],rs[M],cnt;
    char s[10];
    bool q[N];
    int hsh(int x)
    {
        int l=1,r=tot,mid,mz;
        while(l<=r)
        {
            mid=l+r>>1;
            if(hs[mid]<x) l=mid+1;
            else r=mid-1,mz=mid;
        }
        return mz;
    }
    void add(int lst,int l,int r,int &p,int x,int w)
    {
        p=++cnt;
        sz[p]=sz[lst]+w;
        ls[p]=ls[lst];rs[p]=rs[lst];
        if(l==r) return;
        int mid=l+r>>1;
        if(x<=mid) add(ls[lst],l,mid,ls[p],x,w);
        else add(rs[lst],mid+1,r,rs[p],x,w);
    }
    int a,b,L[33],R[33];
    int fd(int l,int r,int k)
    {
        if(l==r) return l;
        int mid=l+r>>1,sl=0,sr=0;
        for(int i=1;i<=a;i++) sl+=sz[ls[L[i]]];
        for(int i=1;i<=b;i++) sr+=sz[ls[R[i]]];
        if(sr-sl>=k)
        {
            for(int i=1;i<=a;i++) L[i]=ls[L[i]];
            for(int i=1;i<=b;i++) R[i]=ls[R[i]];
            return fd(l,mid,k);
        }
        else
        {
            for(int i=1;i<=a;i++) L[i]=rs[L[i]];
            for(int i=1;i<=b;i++) R[i]=rs[R[i]];
            return fd(mid+1,r,k-sr+sl);
        }
    }
    int main()
    {
        tt=n=rd();m=rd();
        for(int i=1;i<=n;i++) ji[i]=v[i]=rd();
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);A[i]=rd();B[i]=rd();
            if(s[0]=='Q') K[i]=rd();
            else ji[++tt]=B[i],q[i]=1;
        }
        sort(ji+1,ji+tt+1);
        hs[1]=ji[1];
        for(int i=2;i<=tt;i++)
            if(ji[i]!=ji[i-1]) hs[++tot]=ji[i];
        for(int i=1,tp;i<=n;i++)
        {
            tp=hsh(v[i]);
            for(int j=i;j<=n;j+=j&(-j))
                add(rt[j],1,tot,rt[j],tp,1);
        }
        for(int i=1,tp;i<=m;i++)
        {
            if(q[i])
            {
                tp=hsh(v[A[i]]);
                for(int j=A[i];j<=n;j+=j&(-j))
                    add(rt[j],1,tot,rt[j],tp,-1);
                tp=hsh(B[i]);
                for(int j=A[i];j<=n;j+=j&(-j))
                    add(rt[j],1,tot,rt[j],tp,1);
                v[A[i]]=B[i];
            }
            else 
            {
                a=b=0;
                for(int j=A[i]-1;j;j-=j&(-j)) L[++a]=rt[j];
                for(int j=B[i];j;j-=j&(-j)) R[++b]=rt[j];
                printf("%d
    ",hs[fd(1,tot,K[i])]);
            }
        }
        return 0;
    }

     

  • 相关阅读:
    7种思维
    微服务架构
    最近面试被问到一个问题,AtomicInteger如何保证线程安全?
    Socket netty ...
    Spring-Boot配置文件web性能(服务器)配置项
    P2P互联网金融企业的四大转型方向
    分布式,微服务 区别联系 理解.
    几个好问题
    netty
    结构化思维
  • 原文地址:https://www.cnblogs.com/lkhll/p/7840689.html
Copyright © 2020-2023  润新知