zoukankan      html  css  js  c++  java
  • 1688 求逆序对

    1688 求逆序对

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 Description

    给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目

    数据范围:N<=105。Ai<=105。时间限制为1s。

    输入描述 Input Description

    第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。

    输出描述 Output Description

    所有逆序对总数.

    样例输入 Sample Input

    4

    3

    2

    3

    2

    样例输出 Sample Output

    3

    数据范围及提示 Data Size & Hint
     

    分类标签 Tags 点此展开 

     
    注意要点:
    1、最后输出的数据要用 long long
    2、代码重点处解释:
         若a[p]>a[j],而且我们用分治早已排成升序形式,所以得出a[p]到mid之间所有数都会大于a[j],所以k=k+mid-p+1,  +1补充我们减去的a[p]。
    归并排序求逆序对
    #include<cstdio>
    #include<iostream>
    #define N 100100
    using namespace std;
    int a[N],b[N],n;
    long long k;
    void binary_chop(int l,int r){
        if(l==r) return ;
        int mid=(l+r>>1);
        binary_chop(l,mid);binary_chop(mid+1,r);
        int p=l,q=l,j=mid+1;
        while(p<=mid&&j<=r){
            if(a[p]>a[j]){
                k+=mid-p+1;//重点
                b[q++]=a[j++];
            }
            else{
                b[q++]=a[p++];
            }
        }
        while(p<=mid) b[q++]=a[p++];
        while(j<=r) b[q++]=a[j++];
        for(int i=l;i<=r;i++) a[i]=b[i];
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",a+i);
        }
        binary_chop(1,n);
        cout<<k<<endl;
        return 0;
    }

    树状数组求逆序对

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=1e5+10;
    int n,cnt,a[N],b[N],c[N];
    ll ans;
    inline int lowbit(int x){
        return x&-x;
    }
    void updata(int p,int v){
        for(int i=p;i<=n;i+=lowbit(i)) c[i]+=v;
    }
    int query(int p){
        int res=0;
        for(int i=p;i;i-=lowbit(i)) res+=c[i];
        return res;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        memcpy(b,a,sizeof a);
        sort(b+1,b+n+1);
        cnt=unique(b+1,b+n+1)-(b+1);
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
        for(int i=1;i<=n;i++){
            ans+=(ll)(query(cnt)-query(a[i]));
            updata(a[i],1);
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    spring aop简单理解
    动态代理
    静态代理
    spring的i o c简单回顾
    java注解的概念理解
    Eclipse中配置Tomcat
    java中Optional和Stream流的部分操作
    java中的stream的Map收集器操作
    java中的二进制运算简单理解
    Class.forName和ClassLoader.loadClass区别(转)
  • 原文地址:https://www.cnblogs.com/shenben/p/5560330.html
Copyright © 2011-2022 走看看