zoukankan      html  css  js  c++  java
  • p1098 逆序对

    传送门

    题目

    输入格式:

    第一行,一个数n,表示序列中有n个数。

    第二行n个数,表示给定的序列。

    输出格式:

    给定序列中逆序对的数目。

    数据范围:

    对于50%的数据,n≤2500

    对于100%的数据,n≤40000。

    分析

    使用分治的思想将序列不断分为两段,然后将这两段进行归并排序,因为每段已经排好序,所有每次增加的逆序对个数即为第一个(有序序列长度-需合并的位置+1)

    同时我们还可以用树状数组求解,我们按大小排序,依次插入到它原本所在位置,所以逆序对个数即为在它之前插入的位置比它靠后的数的总个数

    代码

    归并排序版

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int a[100000],t[100000];
    int ans;
    void mer(int le,int mid,int ri){
          int i=le,j=mid+1,k=le;
          while(i<=mid&&j<=ri){
              if(a[i]>a[j]){
                  t[k++]=a[j++];
                  ans+=(mid-i+1);
              }else t[k++]=a[i++];
          }
          for(i;i<=mid;i++)t[k++]=a[i];
          for(j;j<=ri;j++)t[k++]=a[j];
          for(i=le;i<=ri;i++)a[i]=t[i];
    }
    void go(int le,int ri){
          if(le<ri){
              int mid=(le+ri)>>1;
              go(le,mid);
              go(mid+1,ri);
              mer(le,mid,ri);
          }
    }
    int main(){
          int n,m,i,j,k;
          cin>>n;
          for(i=1;i<=n;i++){
              cin>>a[i];
          }
          go(1,n);
          cout<<ans<<endl;
          return 0;
    }

    树状数组版

    #include<bits/stdc++.h>
    using namespace std;
    inline void read(int &x){
          int f=1;x=0;char s=getchar();
          while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
          while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
          x*=f;
    }
    struct node {
          int pl,d;
    }a[110000];
    int c[110000],n;
    inline bool cmp(const node &x,const node &y){return x.d<y.d;}
    inline int lb(int x){return x&(-x);}
    inline void add(int x,int k){while(x<=n)c[x]+=k,x+=lb(x);}
    inline int q(int x){int ans=0;while(x)ans+=c[x],x-=lb(x);return ans;}
    int main()
    {     int i,ans=0;
          read(n);
          for(i=1;i<=n;i++){
             read(a[i].d);
             a[i].pl=i;
          }
          sort(a+1,a+n+1,cmp);  
          for(i=1;i<=n;i++){
               add(a[i].pl,1);
               ans+=i-q(a[i].pl-1)-1;
          }
          printf("%d ",ans);
          return 0;
    }

  • 相关阅读:
    又见Dooyoul
    用premake编译跨平台opencv程序
    [try it] 使用Apache Ant
    用OllyDbg做破解
    什么是SEO
    SEO最新百度排名算法调整
    SEO网站外链的建设
    SEO网站title优化
    网站title优化应注意的细节
    [ios]设置ARC 【转】
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9004218.html
Copyright © 2011-2022 走看看