zoukankan      html  css  js  c++  java
  • bzoj3295 动态逆序对

    Description

    对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

    Input

    输入第一行包含两个整数nm,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。

    Output

    输出包含m行,依次为删除每个元素之前,逆序对的个数。

    将原数列建立归并树,归并树每个节点记录区间排序后结果、被删除的数的个数、树状数组记录前i个数被删了几个,每删除一个数前查找左边比它大的数和右边比它小的数的个数并更新答案。

    #include<cstdio>
    #include<algorithm>
    inline int read(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    inline void mins(int&a,int b){if(a>b)a=b;}
    inline void maxs(int&a,int b){if(a<b)a=b;}
    long long ans=0;
    int t[100005],v[100005],id[100005];
    int vs[20][100005],bit[20][100005],dt[20][100005];
    int X,v0;
    void build(int L,int R,int h=0){
        int*x=vs[h];
        if(L<R){
            int M=L+R>>1;
            build(L,M,h+1);
            build(M+1,R,h+1);
            int p1=L,p2=M+1,*p3=x+L,*y=vs[h+1];
            while(p1<=M&&p2<=R)*(p3++)=y[(y[p1]<y[p2]?p1:p2)++];
            while(p1<=M)*(p3++)=y[p1++];
            while(p2<=R)*(p3++)=y[p2++];
        }else x[L]=v[L];
    }
    void s1(int L,int R,int h=0){
        int*x=vs[h];
        if(R<X){
            int p=std::upper_bound(x+L,x+R+1,v0)-(x+L);
            ans-=R+1-L-p;
            for(int*a=bit[h]+L-1;p;p-=p&-p)ans-=a[p];
            ans+=dt[h][L];
            return;
        }
        if(L!=R){
            int M=L+R>>1;
            s1(L,M,h+1);
            if(X-1>M)s1(M+1,R,h+1);
        }
    }
    void s2(int L,int R,int h=0){
        int*x=vs[h];
        if(X<L){
            int p=std::lower_bound(x+L,x+R+1,v0)-(x+L);
            ans-=p;
            for(int*a=bit[h]+L-1;p;p-=p&-p)ans+=a[p];
            return;
        }
        if(L!=R){
            int M=L+R>>1;
            if(X<M)s2(L,M,h+1);
            s2(M+1,R,h+1);
        }
    }
    void del(int L,int R,int h=0){
        int*x=vs[h];
        ++dt[h][L];
        int p=std::lower_bound(x+L,x+R+1,v0)-(x+L)+1;
        for(int*a=bit[h]+L-1,N=R-L+1;p<=N;p+=p&-p)++a[p];
        if(L!=R){
            int M=L+R>>1;
            if(X<=M)del(L,M,h+1);
            else del(M+1,R,h+1);
        }
    }
    int n,m;
    int main(){
        n=read();m=read();
        for(int i=1,a;i<=n;i++){
            v[i]=a=read();
            id[a]=i;
            ans+=i-1;
            for(int w=a;w;w-=w&-w)ans-=t[w];
            while(a<=n)++t[a],a+=a&-a;
        }
        build(1,n);
        for(int i=1;i<=m;i++){
            printf("%lld
    ",ans);
            v0=read();
            X=id[v0];
            s1(1,n);
            s2(1,n);
            del(1,n);
        }
        return 0;
    }
  • 相关阅读:
    SQL学习
    FOR XML PATH
    IOS学习网址
    weak nonatomic strong等介绍(ios)
    UVALive3045 POJ2000 ZOJ2345 Gold Coins
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA10905 Children's Game
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5347766.html
Copyright © 2011-2022 走看看