zoukankan      html  css  js  c++  java
  • 求逆序对的两种方法(树状数组/归并排序)

    例题:poj2299

    看代码就好了

    树状数组:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<string>
    #include<string.h>
    #include<set>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #include<iterator>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define MOD 100000007
    #define ll long long
    #define INF 0x3f3f3f3f
    const double pi = acos(-1.0);
    const int Maxn=50000;
    using namespace std;
    inline int scan()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    /**********************************树状数组+离散化*******************************/
    ll c[500010];
    ll n;
    ll lowbit(ll x){
        return x&-x;
    }
    void add(ll i){
        while(i<=n){
            c[i]++;
            i+=lowbit(i);
        }
    }
    ll getnum(ll i){
        ll num=0;
        while(i>0){
            num+=c[i];
            i-=lowbit(i);
        }
        return num;
    }
    struct node{
        ll v,i;
        friend bool operator < (node a,node b){
            return a.v<b.v;
        }
    }nd[500010];
    int main(){
        while(scanf("%lld",&n)&&n){
            mem(nd,0);
            mem(c,0);
            map<int,int>mp;
            int v;
            ll k=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&v);
                if(!mp[v]){//要去重!!! 
                    nd[++k].v=v;
                    nd[k].i=k;
                    mp[v]=1;
                }
            }
            n=k;
            sort(nd+1,nd+n+1);
            ll ans=0;
            for(int i=1;i<=n;i++){
                add(nd[i].i);
                ans+=(1ll*i-getnum(nd[i].i));//已插入i个数,getnum[nd[i].i]是比nd[i].i小的数的个数i-getnum[nd[i].i]就是i个数前比他大的数
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    归并排序:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<string>
    #include<string.h>
    #include<set>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #include<iterator>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define MOD 100000007
    #define ll long long
    #define INF 0x3f3f3f3f
    const double pi = acos(-1.0);
    const int Maxn=50000;
    using namespace std;
    inline int scan()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int c[500010];
    vector<int>vec;
    int n;
    ll ans;
    void mergersort(int l,int r){
        if(l==r){
            return ;
        }
        int mid=(l+r)>>1;
        mergersort(l,mid);
        mergersort(mid+1,r);
        vec.clear();
        int q=l,p=mid+1;
        while(q<=mid&&p<=r){
            if(c[q]<=c[p]){
                vec.push_back(c[q++]);
            }else{
                vec.push_back(c[p++]);
                ans+=(mid-q+1);///l~mid中剩余数的个数就是mid-q+1,而如果c[q]>c[p],那c[p]就要交换mid-q+1次
            }
        }
        while(q<=mid) vec.push_back(c[q++]);
        while(p<=r) vec.push_back(c[p++]);
        q=l;
        for(int i=0;i<vec.size();i++){
            c[q++]=vec[i];
        }
    }
    int main(){
        while(scanf("%d",&n)&&n){
            ans=0;
            mem(c,0);
            for(int i=1;i<=n;i++){
                scanf("%d",&c[i]);
            }
            mergersort(1,n);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Oracle列转行函数Listagg以及pivot查询示例
    Java执行操作系统命令
    JUnit学习之hamcrest、testSuite介绍及测试原则
    JUnit学习之JUnit的基本介绍
    Oracle笔记-Multitable INSERT 的用法
    Oracle 11g 新特性 --SQL Plan Management 说明
    Java习惯用法总结
    将Eclipse的Java Project转换为Dynamic Web Project
    在Eclipse中调试web项目
    在Eclipse中添加Servlet-api.jar的方法
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10827554.html
Copyright © 2011-2022 走看看