zoukankan      html  css  js  c++  java
  • BZOJ1901Zju2112 Dynamic Rankings——树状数组套主席树

    题目描述

    给定一个含有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继续回答上面的问题。

    输入

    第一行有两个正整数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

    输出

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

    样例输入

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

    样例输出

    3
    6
      带修改主席树经典题,树状数组上每个点建一棵主席树,存树状数组上这个点包含的序列中点的信息,修改看成删除和插入,每次操作跳lowbit。
    不会带修改主席树的参见->主席树讲解
    #include<set>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    int n,m;
    char ch[2];
    int x,y,z;
    int cnt;
    int tot;
    int num;
    int ls[8000010];
    int rs[8000010];
    int sum[8000010];
    int root[100010];
    int s[100010];
    int t[100010];
    int a[100010];
    int updata(int pre,int l,int r,int k)
    {
        int rt=++cnt;
        if(l==r)
        {
            sum[rt]=sum[pre]+1;
            return rt;
        }
        ls[rt]=ls[pre];
        rs[rt]=rs[pre];
        sum[rt]=sum[pre]+1;
        int mid=(l+r)>>1;
        if(k<=mid)
        {
            ls[rt]=updata(ls[pre],l,mid,k);
        }
        else
        {
            rs[rt]=updata(rs[pre],mid+1,r,k);
        }
        return rt;
    }
    int downdata(int pre,int l,int r,int k)
    {
        int rt=++cnt;
        if(l==r)
        {
            sum[rt]=sum[pre]-1;
            return rt;
        }
        ls[rt]=ls[pre];
        rs[rt]=rs[pre];
        sum[rt]=sum[pre]-1;
        int mid=(l+r)>>1;
        if(k<=mid)
        {
            ls[rt]=downdata(ls[pre],l,mid,k);
        }
        else
        {
            rs[rt]=downdata(rs[pre],mid+1,r,k);
        }
        return rt;
    }
    void add(int v,int x)
    {
        for(int i=x;i<=n;i+=i&-i)
        {
            root[i]=updata(root[i],0,1e9,v);
        }
    }
    void del(int v,int x)
    {
        for(int i=x;i<=n;i+=i&-i)
        {
            root[i]=downdata(root[i],0,1e9,v);
        }
    }
    int query(int l,int r,int k)
    {
        if(l==r)
        {
            return l;
        }
        int ans=0;
        int res=0;
        for(int i=1;i<=num;i++)
        {
            res+=sum[ls[s[i]]];
        }
        for(int i=1;i<=tot;i++)
        {
            ans+=sum[ls[t[i]]];
        }
        int mid=(l+r)>>1;
        if(ans-res>=k)
        {
            for(int i=1;i<=num;i++)
            {
                s[i]=ls[s[i]];
            }
            for(int i=1;i<=tot;i++)
            {
                t[i]=ls[t[i]];
            }
            return query(l,mid,k);
        }
        else
        {
            for(int i=1;i<=num;i++)
            {
                s[i]=rs[s[i]];
            }
            for(int i=1;i<=tot;i++)
            {
                t[i]=rs[t[i]];
            }
            return query(mid+1,r,k-(ans-res));
        }
    }
    void ask(int l,int r,int x)
    {
        num=0;
        tot=0;
        for(int i=l;i;i-=i&-i)
        {
            s[++num]=root[i];
        }
        for(int i=r;i;i-=i&-i)
        {
            t[++tot]=root[i];
        }
        printf("%d
    ",query(0,1e9,x));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            add(a[i],i);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ch);
            if(ch[0]=='Q')
            {
                scanf("%d%d%d",&x,&y,&z);
                ask(x-1,y,z);
            }
            else
            {
                scanf("%d%d",&x,&y);
                del(a[x],x);
                a[x]=y;
                add(a[x],x);
            }
        }
    }
  • 相关阅读:
    LeetCode 275. H-Index II
    LeetCode 274. H-Index
    LeetCode Gray Code
    LeetCode 260. Single Number III
    LeetCode Word Pattern
    LeetCode Nim Game
    LeetCode 128. Longest Consecutive Sequence
    LeetCode 208. Implement Trie (Prefix Tree)
    LeetCode 130. Surrounded Regions
    LeetCode 200. Number of Islands
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9513584.html
Copyright © 2011-2022 走看看