zoukankan      html  css  js  c++  java
  • 洛谷试炼场 4-17 主席树


    layout: post
    title: 洛谷试炼场 4-17 主席树
    author: "luowentaoaa"
    catalog: true
    mathjax: true
    tags:
    - 主席树
    - 数据结构
    - 洛谷


    P3834 【模板】可持久化线段树 1(主席树)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    int n,m,cnt,root[maxn],a[maxn],x,y,k;
    struct node{int l,r,sum;}T[maxn*20];
    vector<int>v;
    int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    void update(int l,int r,int &x,int y,int pos){
        T[++cnt]=T[y],T[cnt].sum++,x=cnt;
        if(l==r)return;
        int mid=(l+r)/2;
        if(mid>=pos)update(l,mid,T[x].l,T[y].l,pos);
        else update(mid+1,r,T[x].r,T[y].r,pos);
    }
    int query(int l,int r,int x,int y,int k){
        if(l==r)return l;
        int mid=(l+r)/2;
        int sum=T[T[y].l].sum-T[T[x].l].sum;
        if(sum>=k)return query(l,mid,T[x].l,T[y].l,k);
        else return query(mid+1,r,T[x].r,T[y].r,k-sum);
    }
    template <class T>
    inline bool read(T &ret){
        char c;int sgn;if(c=getchar(),c==EOF)return 0;
        while(c!='-'&&(c<'0'||c>'9'))c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');
        while(c=getchar(),c>='0'&&c<='9')ret=ret*10+(c-'0');ret*=sgn;return 1;
    }
    inline void out(int x){if(x>9)out(x/10);putchar(x%10+'0');}
    int main()
    {
       /* std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);*/
        read(n);read(m);
        for(int i=1;i<=n;i++)read(a[i]),v.push_back(a[i]);
        sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
        for(int i=1;i<=n;i++)update(1,n,root[i],root[i-1],getid(a[i]));
        while(m--){
           // cin>>x>>y>>k;
           read(x);read(y);read(k);
            out(v[query(1,n,root[x-1],root[y],k)-1]);puts("");
           // cout<<v[query(1,n,root[x-1],root[y],k)-1]<<endl;
        }
        return 0;
    }
    

    P2617 Dynamic Rankings (主席树套树状数组)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    struct node{int l,r,sum;}s[maxn*20];
    vector<int>v;
    struct quest{char op;int x,y,k;}Q[maxn];
    inline int get(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    inline int lowbit(int x){return x&(-x);}
    int a[maxn],b[maxn],T[maxn];
    int n,m;
    int tot;
    int len;
    int temp[2][100],cnt[2];
    void update(int &now,int l,int r,int pos,int val){
        if(now==0)now=++tot;
        s[now].sum+=val;
        if(l==r)return;
        int mid=(l+r)/2;
        if(pos<=mid)update(s[now].l,l,mid,pos,val);
        else update(s[now].r,mid+1,r,pos,val);
    }
    void uptree(int x,int val){
        int pos=get(a[x]);
        for(int i=x;i<=n;i+=lowbit(i))update(T[i],1,len,pos,val);
    }
    int query(int l,int r,int k){
        if(l==r)return l;
        int x=0,mid=(l+r)/2;
        for(int i=1;i<=cnt[1];i++)x+=s[s[temp[1][i]].l].sum;
        for(int i=1;i<=cnt[0];i++)x-=s[s[temp[0][i]].l].sum;
        if(k<=x){
            for(int i=1;i<=cnt[1];i++)temp[1][i]=s[temp[1][i]].l;
            for(int i=1;i<=cnt[0];i++)temp[0][i]=s[temp[0][i]].l;
            return query(l,mid,k);
        }
        else{
            for(int i=1;i<=cnt[1];i++)temp[1][i]=s[temp[1][i]].r;
            for(int i=1;i<=cnt[0];i++)temp[0][i]=s[temp[0][i]].r;
            return query(mid+1,r,k-x);
        }
    }
    int qutree(int x,int y,int k){
        memset(temp,0,sizeof(temp));
        cnt[0]=cnt[1]=0;
        for(int i=y;i;i-=lowbit(i))temp[1][++cnt[1]]=T[i];
        for(int i=x-1;i;i-=lowbit(i))temp[0][++cnt[0]]=T[i];
        return query(1,len,k);
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>a[i],v.push_back(a[i]);
        for(int i=1;i<=m;i++){
            cin>>Q[i].op>>Q[i].x>>Q[i].y;
            if(Q[i].op=='Q')cin>>Q[i].k;
            else v.push_back(Q[i].y);
        }
        sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
        len=v.size();
        for(int i=1;i<=n;i++)uptree(i,1);
        for(int i=1;i<=m;i++){
            if(Q[i].op=='Q')cout<<v[qutree(Q[i].x,Q[i].y,Q[i].k)-1]<<endl;
            else{
                uptree(Q[i].x,-1);
                a[Q[i].x]=Q[i].y;
                uptree(Q[i].x,1);
            }
        }
        return 0;
    }
    

    [P3157 CQOI2011]动态逆序对 (主席树套树状数组)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    struct node{int l,r,sum;}T[maxn*20];
    int a[maxn],p[maxn],c[maxn],uu,pre[maxn],suf[maxn];
    int xx[100],yy[100];
    int n,m,ooo,rot[maxn];
    inline int lowbit(int x){return x&(-x);}
    void add(int x,int k){
        for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;
    }
    int getsum(int x){
        int k=0;
        for(int i=x;i;i-=lowbit(i))k+=c[i];return k;
    }
    int query(int o,int l,int r,int x,int y){
        if(!o)return 0;
        if(l>=x&&r<=y)return T[o].sum;
        else{
            int mid=(l+r)/2;
            int ans=0;
            if(x<=mid)ans+=query(T[o].l,l,mid,x,y);
            if(mid<y)ans+=query(T[o].r,mid+1,r,x,y);
            return ans;
        }
    }
    int queryRange(int uu,int vv,int xx,int yy){
        int tmp=0;
        for(int i=uu-1;i;i-=lowbit(i))
            tmp-=query(rot[i],1,n,xx,yy);
        for(int i=vv;i;i-=lowbit(i))
            tmp+=query(rot[i],1,n,xx,yy);
        return tmp;
    }
    void update(int &rt,int l,int r,int x){
        if(!rt)rt=++ooo;
        T[rt].sum++;
        if(l==r)return;
        int mid=(l+r)/2;
        if(x<=mid)update(T[rt].l,l,mid,x);
        if(mid<x)update(T[rt].r,mid+1,r,x);
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        cin>>n>>m;
        ll ans=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            p[a[i]]=i;
            pre[i]=getsum(n)-getsum(a[i]);
            ans+=pre[i];
            add(a[i],1);
        }
        memset(c,0,sizeof(c));
        for(int i=n;i>=1;i--){
            suf[i]=getsum(a[i]-1);
            add(a[i],1);
        }
        while(m--){
            cout<<ans<<endl;
            cin>>uu;
            uu=p[uu];
            ans-=pre[uu]+suf[uu];
            ans+=queryRange(1,uu-1,a[uu]+1,n);
            ans+=queryRange(uu+1,n,1,a[uu]-1);
            for(int i=uu;i<=n;i+=lowbit(i))
                update(rot[i],1,n,a[uu]);
        }
        return 0;
    }
    
  • 相关阅读:
    从arduino到32单片机的转型
    设备驱动基础学习--poll
    设备驱动基础学习--阻塞和非阻塞读写
    转载:Linux 时钟基础学习
    转载:linux capability深入分析
    设备驱动基础学习--/proc下增加节点
    设备驱动基础学习--platform driver简单实现
    设备驱动基础学习--misc device简单实现
    转载:initcall
    Linux进程虚拟地址空间
  • 原文地址:https://www.cnblogs.com/luowentao/p/10360012.html
Copyright © 2011-2022 走看看