zoukankan      html  css  js  c++  java
  • HDU 1394 Minimum Inversion Number 线段树 单点更新 求逆序数

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1394

    题意:

    a1, a2, …, an-1, an
    a2, a3, …, an, a1
    a3, a4, …, an, a1, a2

    an, a1, a2, …, an-1
    求其中最小的逆序数的个数

    题解:

    从a[0]开始扫描,找比a[0]大的个数,也就是询问区间(a[0],n-1)中点的个数,然后再插入a[0],更新父节点

    求最小:设逆序数为sum,x[0]后面比它小的一定是x[0]个。那么移到末尾后,比x[0]大的数的后面比它小的数统统加一,也就是加(n - a[0] - 1),然后它放到末尾了,他原来的后面比它小的数变为0,也就是sum = sum + (n - a[0] - 1) - a[0];’

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define MS(a) memset(a,0,sizeof(a))
     5 #define MP make_pair
     6 #define PB push_back
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 const int maxn = 1e5+10;
    17 
    18 int sum[maxn<<2],x[maxn];
    19 
    20 void pushup(int rt){
    21     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    22 }
    23 
    24 void build(int l,int r,int rt){
    25     sum[rt] = 0;
    26     if(l == r) return;
    27     int mid = (l+r)/2;
    28     build(l,mid,rt<<1);
    29     build(mid+1,r,rt<<1|1);
    30 }
    31 
    32 void update(int l,int r,int rt,int p){
    33     if(l == r){
    34         sum[rt] = 1;
    35         return ;
    36     }
    37 
    38     int mid = (l+r)/2;
    39     if(p <= mid)
    40         update(l,mid,rt<<1,p);
    41     else if(p > mid)
    42         update(mid+1,r,rt<<1|1,p);
    43     pushup(rt);
    44 }
    45 
    46 int query(int l,int r,int rt, int L,int R){
    47     if(L<=l && r<=R)
    48         return sum[rt];
    49 
    50     int mid = (l+r)/2;
    51     int ans = 0;
    52     // if(L>mid)
    53     //  ans += query(mid+1,r,rt<<1|1,L,R);
    54     // else if(R<mid)
    55     //  ans += query(l,mid,rt<<1,L,R);
    56     // else
    57     //  ans += query(l,mid,rt<<1,L,R)+query(mid+1,r,rt<<1|1,L,R);
    58     if(L<=mid)
    59         ans += query(l,mid,rt<<1,L,R);
    60     if(R>mid)
    61         ans += query(mid+1,r,rt<<1|1,L,R);
    62     return ans;
    63 }
    64 
    65 int main(){
    66     int n;
    67     while(cin>>n){
    68         int s = 0;
    69         build(0,n-1,1);
    70         for(int i=0; i<n; i++){
    71             scanf("%d",&x[i]);
    72             s += query(0,n-1,1,x[i],n-1);
    73             update(0,n-1,1,x[i]);
    74         }
    75 
    76         int ans = s;
    77         for(int i=0; i<n; i++){
    78             s = s + (n-x[i]-1) - x[i];
    79             ans = min(ans,s);
    80         }
    81 
    82         cout << ans << endl;
    83     }
    84 
    85     return 0;
    86 }
  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827666.html
Copyright © 2011-2022 走看看