• 逆序对


    逆序对

    n(1<=n<=100000)个数,输出其中逆序对的对数。

    输入:

    5
    2 3 1 5 4

    输出:

    3

    离散化+树状数组

    代码:

      1 #include <bits/stdc++.h>
      2 const int MAXN=1000;
      3 using namespace std;
      4 
      5 struct node{
      6     long long v;
      7     int id;
      8     bool operator <(const node&p) const{
      9         return v<p.v;
     10     }
     11 };
     12 node a[MAXN+10];
     13 long long c[MAXN+10];
     14 long long b[MAXN+10];
     15 int n;
     16 
     17 inline int lowbit(int x){
     18     return x&-x;
     19 }
     20 
     21 long long Query(int x){
     22     long long ans=0;
     23     while(x){
     24         ans+=c[x];
     25         x-=lowbit(x);
     26     }
     27     return ans;
     28 }
     29 
     30 void Change(int x){
     31     while(x<=n){
     32         c[x]++;
     33         x+=lowbit(x);
     34     }
     35 }
     36 
     37 void printA(){
     38     cout<<"a数组"<<endl;
     39     cout<<setw(7)<<"id:"<<" "; 
     40     for(int i=1;i<=n;i++){
     41         cout<<a[i].id<<" ";
     42     }
     43     cout<<endl;
     44     cout<<setw(7)<<"value:"<<" "; 
     45     for(int i=1;i<=n;i++){
     46         cout<<a[i].v<<" ";
     47     }
     48     cout<<endl;
     49 } 
     50 
     51 void printB(){
     52     cout<<"b数组"<<endl;
     53     cout<<setw(7)<<"b[i]:"<<" "; 
     54     for(int i=1;i<=n;i++){
     55         cout<<b[i]<<" ";
     56     }
     57     cout<<endl;
     58 } 
     59 
     60 void printC(){
     61     cout<<"c数组"<<endl;
     62     cout<<setw(7)<<"c[i]:"<<" "; 
     63     for(int i=1;i<=n;i++){
     64         cout<<c[i]<<" ";
     65     }
     66     cout<<endl;
     67 } 
     68 
     69 int main(){
     70     freopen("in.txt","r",stdin);
     71     freopen("out.txt","w",stdout);
     72     cin>>n;
     73     memset(a,0,sizeof(a));
     74     memset(b,0,sizeof(b));
     75     memset(c,0,sizeof(c));
     76     //离散化 
     77     for(int i=1;i<=n;i++){
     78         cin>>a[i].v;
     79         a[i].id=i;
     80     }
     81     printA();
     82     sort(a+1,a+n+1);
     83     cout<<endl<<"-----------------排序后-----------------"<<endl<<endl;; 
     84     printA();
     85     int pre=-1;
     86     int prevalue=0;
     87     for(int i=1;i<=n;i++){
     88         //判断离散化的时候两个值是否相同
     89         //离散化很简单,就是排序后一个个输出就好
     90         //下标的话依次递增就好了 
     91         if(pre!=a[i].v){
     92             pre=a[i].v;
     93             a[i].v=++prevalue;
     94         }
     95         else a[i].v=prevalue;
     96     }
     97     cout<<endl<<"-----------------离散化后-----------------"<<endl<<endl; 
     98     printA();
     99     //这部分就是排序后给它逆回来 
    100     for(int i=1;i<=n;i++){
    101         cout<<"i: "<<i<<" a[i].id: "<<a[i].id<<" a[i].v:"<<a[i].v<<endl; 
    102         b[a[i].id]=a[i].v;
    103     }
    104     printB();
    105     long long s=0;
    106     //逆序求解 
    107     cout<<endl<<"-----------------逆序求解-----------------"<<endl<<endl; 
    108     printC(); 
    109     for(int i=n;i>=1;i--){
    110         cout<<"i: "<<i<<endl;
    111         Change(b[i]);
    112         s+=Query(b[i]-1);
    113         printC(); 
    114         cout<<"i: "<<i<<" b[i]: "<<b[i]<<" Query(b[i]-1):"<<Query(b[i]-1)<<endl; 
    115     } 
    116     cout<<endl<<"-----------------结果-----------------"<<endl<<endl;; 
    117     cout<<s<<endl;;
    118     return 0;
    119 } 

    运行过程:

    a数组
    id: 1 2 3 4 5
    value: 2 3 1 5 4

    -----------------排序后-----------------

    a数组
    id: 3 1 2 5 4
    value: 1 2 3 4 5

    -----------------离散化后-----------------

    a数组
    id: 3 1 2 5 4
    value: 1 2 3 4 5
    i: 1 a[i].id: 3 a[i].v:1
    i: 2 a[i].id: 1 a[i].v:2
    i: 3 a[i].id: 2 a[i].v:3
    i: 4 a[i].id: 5 a[i].v:4
    i: 5 a[i].id: 4 a[i].v:5
    b数组
    b[i]: 2 3 1 5 4

    -----------------逆序求解-----------------

    c数组
    c[i]: 0 0 0 0 0
    i: 5
    c数组
    c[i]: 0 0 0 1 0
    i: 5 b[i]: 4 Query(b[i]-1):0
    i: 4
    c数组
    c[i]: 0 0 0 1 1
    i: 4 b[i]: 5 Query(b[i]-1):1
    i: 3
    c数组
    c[i]: 1 1 0 2 1
    i: 3 b[i]: 1 Query(b[i]-1):0
    i: 2
    c数组
    c[i]: 1 1 1 3 1
    i: 2 b[i]: 3 Query(b[i]-1):1
    i: 1
    c数组
    c[i]: 1 2 1 4 1
    i: 1 b[i]: 2 Query(b[i]-1):1

    -----------------结果-----------------

    3

    这里的前缀和是比这个数小的个数,比如说倒数第二个数5,那么就是求的5后面比我小的数之和,也就是4的前缀和。 

    树状数组在这里用的就是前缀和。


    测试离散化:

    输入数据:

    5
    4 6 2 10 8

    运行过程:

    a数组
    id: 1 2 3 4 5
    value: 4 6 2 10 8

    -----------------排序后-----------------

    a数组
    id: 3 1 2 5 4
    value: 2 4 6 8 10

    -----------------离散化后-----------------

    a数组
    id: 3 1 2 5 4
    value: 1 2 3 4 5
    i: 1 a[i].id: 3 a[i].v:1
    i: 2 a[i].id: 1 a[i].v:2
    i: 3 a[i].id: 2 a[i].v:3
    i: 4 a[i].id: 5 a[i].v:4
    i: 5 a[i].id: 4 a[i].v:5
    b数组
    b[i]: 2 3 1 5 4

    -----------------逆序求解-----------------

    c数组
    c[i]: 0 0 0 0 0
    i: 5
    c数组
    c[i]: 0 0 0 1 0
    i: 5 b[i]: 4 Query(b[i]-1):0
    i: 4
    c数组
    c[i]: 0 0 0 1 1
    i: 4 b[i]: 5 Query(b[i]-1):1
    i: 3
    c数组
    c[i]: 1 1 0 2 1
    i: 3 b[i]: 1 Query(b[i]-1):0
    i: 2
    c数组
    c[i]: 1 1 1 3 1
    i: 2 b[i]: 3 Query(b[i]-1):1
    i: 1
    c数组
    c[i]: 1 2 1 4 1
    i: 1 b[i]: 2 Query(b[i]-1):1

    -----------------结果-----------------

    3

  • 相关阅读:
    SQL Server中使用convert进行日期转换
    杂记
    sqlserver表分区与调优与行列转换
    HttpModule的认识与深入理解及MVC运行机制
    再谈委托
    ASP.NET forms凭据设置和跳转的几种方法
    IOS学习网址
    Activator.CreateInstance 方法 (Type) 的用法
    update多表更新的2种方式
    SQL自定义函数split分隔字符串
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7754694.html
Copyright © 2020-2023  润新知