zoukankan      html  css  js  c++  java
  • (线段树)hdoj1394-Minimum Inversion Number 逆序对

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. 

    For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following: 

    a1, a2, ..., an-1, an (where m = 0 - the initial seqence) 
    a2, a3, ..., an, a1 (where m = 1) 
    a3, a4, ..., an, a1, a2 (where m = 2) 
    ... 
    an, a1, a2, ..., an-1 (where m = n-1) 

    You are asked to write a program to find the minimum inversion number out of the above sequences. 

    InputThe input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
    OutputFor each case, output the minimum inversion number on a single line. 
    Sample Input

    10
    1 3 6 9 0 8 5 7 4 2

    Sample Output

    16

    解题思路:
    线段树各个结点记录m——n之间有多少个数已经出现。
     1 #include <iostream>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 typedef unsigned long long ull;
     9 struct node
    10 {
    11     int left,right,mid;
    12     int num;
    13 }st[50005];
    14 void init(int l,int r,int n)
    15 {
    16     st[n].left=l;
    17     st[n].right=r;
    18     st[n].mid=(l+r)/2;
    19     st[n].num=0;
    20     if(l+1==r)
    21         return;
    22     init(l,(l+r)/2,2*n);
    23     init((l+r)/2,r,2*n+1);
    24 }
    25 void update(int pri,int n)
    26 {
    27     st[n].num++;
    28     if(st[n].left+1==st[n].right)
    29         return;
    30     if(pri>=st[n].mid)
    31         update(pri,2*n+1);
    32     else
    33         update(pri,2*n);
    34 }
    35 int query(int pri,int n)
    36 {
    37     if(st[n].left+1==st[n].right)
    38         return st[n].num;
    39     if(pri>=st[n].mid)
    40         return query(pri,2*n)+query(pri,2*n+1);
    41     else
    42         return  query(pri,2*n);
    43 
    44 }
    45 int n;
    46 int tem;
    47 int an=0;
    48 int ans=0;
    49 int x[5005];
    50 int main()
    51 {
    52     while(~scanf("%d",&n))
    53     {
    54         an=0;
    55         init(1,n+1,1);
    56         int i;
    57         for(i=1;i<=n;i++)
    58         {
    59             scanf("%d",&tem);
    60             x[i]=n-tem;
    61             an+=query(n-tem,1);
    62             update(n-tem,1);
    63 //            an+=query(tem+1,1);
    64 //            update(tem+1,1);
    65 //            printf("i=%d an=%d
    ",i,an);
    66         }
    67         ans=an;
    68         for(i=1;i<=n;i++)
    69         {
    70             ans+=(-n+2*x[i]-1);
    71             an=min(ans,an);
    72         }
    73         printf("%d
    ",an);
    74     }
    75 }

     原先的写的好差啊……居然还不T能过……

     1 #include <iostream>
     2 #include<bits/stdc++.h>
     3 #include <stack>
     4 #include <queue>
     5 #include <map>
     6 #include <set>
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <math.h>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef unsigned long long ull;
    14 const int MAX=5e3+5;
    15 int a[MAX],sum[MAX<<2];
    16 int n;
    17 void update(int lo,int l,int r,int k)
    18 {
    19     sum[k]++;
    20     if(l==r)
    21         return;
    22     int mid=l+r>>1;
    23     if(lo<=mid)
    24         update(lo,l,mid,2*k);
    25     else
    26         update(lo,mid+1,r,2*k+1);
    27 }
    28 int query(int left,int l,int r,int k)
    29 {
    30     if(l>=left)
    31         return sum[k];
    32     int mid=l+r>>1;
    33     if(left>mid)
    34         return query(left,mid+1,r,2*k+1);
    35     else
    36         return query(left,l,mid,2*k)+query(left,mid+1,r,2*k+1);
    37 }
    38 int an,he;
    39 int main()
    40 {
    41     while(~scanf("%d",&n))
    42     {
    43         an=0;
    44         for(int i=0;i<=n*4;i++)
    45             sum[i]=0;
    46         for(int i=1;i<=n;i++)
    47         {
    48             scanf("%d",&a[i]);
    49             update(a[i],0,n-1,1);
    50             if(a[i]!=n-1)
    51                 an+=query(a[i]+1,0,n-1,1);
    52         }
    53         he=an;
    54         for(int i=1;i<n;i++)
    55         {
    56             he=he+n-1-2*a[i];
    57             an=min(an,he);
    58         }
    59         printf("%d
    ",an);
    60     }
    61 }
  • 相关阅读:
    Caffe学习系列(18): 绘制网络模型
    Caffe学习系列(17):模型各层数据和参数可视化
    android ------ RecyclerView 模仿淘宝购物车
    android ------- 开发者的 RxJava 详解
    android -------- 压缩图片文件工具类
    android -------- MVP+DataBinding 的使用
    android -------- ConstraintLayout Group和goneMargin(五)
    android -------- ConstraintLayout Guideline和Barrier(四)
    android -------- ConstraintLayout 宽高比和偏移量比(三)
    android -------- ConstraintLayout 约束属性(二)
  • 原文地址:https://www.cnblogs.com/quintessence/p/6395526.html
Copyright © 2011-2022 走看看