zoukankan      html  css  js  c++  java
  • BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树

    题目:

    emmmm是个权限题


    题解:

    带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改

    修改的时候修改类似树状数组一样进行logn个Insert

    查询的时候同理,树状数组的方法取出和这个位置相关的节点,用数组保存然后计算

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 100005
    #define M 6000005
    using namespace std;
    int n,m,a[N],lst[N],idx;
    int tot,root[N],data[M],ls[M],rs[M],cur1[N],cur2[N];
    int qtype[N],q1[N],q2[N],q3[N];
    char s[233];
    void build(int &k,int l,int r)
    {
        k=++tot;
        if (l==r) return;
        int mid=l+r>>1;
        build(ls[k],l,mid),build(rs[k],mid+1,r);
    }
    void change(int x,int &y,int l,int r,int p,int k)
    {
        data[y=++tot]=data[x]+k,ls[y]=ls[x],rs[y]=rs[x];
        if (l==r) return;
        int mid=l+r>>1;
        if (p<=mid) change(ls[x],ls[y],l,mid,p,k);
        else change(rs[x],rs[y],mid+1,r,p,k);
    }
    
    void add(int p,int num,int x)
    {
        for (;p<=n;p+=p&-p) change(root[p],root[p],1,idx,num,x);
    }
    int query(int ql,int qr,int k)
    {
        int l=1,r=idx;
        for (int p=ql;p;p-=p&-p) cur1[p]=root[p];
        for (int p=qr;p;p-=p&-p) cur2[p]=root[p]; 
        while (l<r)
        {
            int mid=l+r>>1,sum1=0,sum2=0;
            for (int p=ql;p;p-=p&-p) sum1+=data[ls[cur1[p]]];
            for (int p=qr;p;p-=p&-p) sum2+=data[ls[cur2[p]]];
            if (sum2-sum1>=k) 
            {
                for (int p=ql;p;p-=p&-p) cur1[p]=ls[cur1[p]];
                for (int p=qr;p;p-=p&-p) cur2[p]=ls[cur2[p]];
                r=mid;
            }
            else 
            {
                l=mid+1,k-=sum2-sum1;
                for (int p=ql;p;p-=p&-p) cur1[p]=rs[cur1[p]];
                for (int p=qr;p;p-=p&-p) cur2[p]=rs[cur2[p]];
            }
        }
        return lst[l];
    }
    int getpos(int x)
    {
        return lower_bound(lst+1,lst+idx+1,x)-lst;
    }
    bool isQ()
    {
        char c;
        while(c=getchar(),c!='Q' && c!='C');
        return c=='Q';
    }
    int main()
    {
        scanf("%d%d",&n,&m),idx=n;
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]),lst[i]=a[i];
        for (int i=1;i<=m;i++)
        {
            qtype[i]=isQ();
            scanf("%d%d",q1+i,q2+i);
            if (qtype[i]) scanf("%d",q3+i);
            else lst[++idx]=q2[i];
        }
        sort(lst+1,lst+1+idx);
        idx=unique(lst+1,lst+1+idx)-lst-1;
        build(root[0],1,idx);
        for (int i=1;i<=n;i++) root[i]=root[0];
        for (int i=1;i<=n;i++) add(i,getpos(a[i]),1);
        for (int i=1;i<=m;i++)
            if (qtype[i]) printf("%d
    ",query(q1[i]-1,q2[i],q3[i]));
            else 
            {
                add(q1[i],getpos(a[q1[i]]),-1);
                a[q1[i]]=q2[i];
                add(q1[i],getpos(a[q1[i]]),1);
            }
        return 0;
    } 
  • 相关阅读:
    谜题92:双绞线
    谜题91:序列杀手
    谜题90:荒谬痛苦的超类
    谜题89:泛型迷药
    谜题88:原生类型的处理
    谜题87:紧张的关系
    谜题86:有毒的括号垃圾
    谜题85:惰性初始化
    谜题84:被粗暴地中断
    easyUi DataGrid
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8166428.html
Copyright © 2011-2022 走看看