zoukankan      html  css  js  c++  java
  • HDU 1394.Minimum Inversion Number-最小逆序数-完全版线段树(单点增减、区间求和)

    HDU1394.Minimum Inversion Number

    这个题求最小逆序数,先建一个空的树,然后每输入一个值,就先查询一下,查询之后,更新线段树,然后遍历一遍,每次将第一个数放到最后之后,减少的逆序数为x[i],增加的为n-x[i]-1;

    所以该种序列的逆序数为sum+=n-x[i]-x[i]-1。直接遍历的时候找最小值就可以了。

    写的脑子有点乱。。。

    代码:

      1 //c
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<cstdlib>
      8 #include<queue>
      9 #include<stack>
     10 using namespace std;
     11 typedef long long ll;
     12 const int inf=0x3f3f3f3f;
     13 const double eps=1e-5;
     14 const int maxn=5*1e5+10;
     15 #define lson l,m,rt<<1
     16 #define rson m+1,r,rt<<1|1
     17 int sum[maxn<<2],MAX[maxn<<2];
     18 
     19 void PushUp(int rt){
     20     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     21     //MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
     22 }
     23 /*
     24 void build(int l,int r,int rt){
     25     if(l==r){
     26         scanf("%d",&sum[rt]);
     27         //scanf("%d",&MAX[rt]);
     28         return ;
     29     }
     30     int m=(l+r)>>1;
     31     build(lson);
     32     build(rson);
     33     PushUp(rt);
     34 }
     35 */
     36 void build(int l,int r,int rt){
     37     sum[rt]=0;
     38     if(l==r)return ;
     39     int m=(l+r)>>1;
     40     build(lson);
     41     build(rson);
     42 }
     43 void update(int p,int l,int r,int rt){
     44     if(l==r){
     45         sum[rt]++;
     46         return ;
     47     }
     48     int m=(l+r)>>1;
     49     if(p<=m)update(p,lson);
     50     else update(p,rson);
     51     PushUp(rt);
     52 }
     53 /*
     54 //单点增减
     55 void update(int p,int add,int l,int r,int rt){
     56     if(l==r){
     57         sum[rt]+=add;
     58         return ;
     59     }
     60     int m=(l+r)>>1;
     61     if(p<=m)update(p,add,lson);
     62     else update(p,add,rson);
     63     PushUp(rt);
     64 }
     65 */
     66 /*
     67 //单点更新
     68 void update(int p,int sc,int l,int r,int rt){
     69     if(l==r){
     70         MAX[rt]=sc;
     71         return ;
     72     }
     73     int m=(l+r)>>1;
     74     if(p<=m)update(p,sc,lson);
     75     else update(p,sc,rson);
     76     PushUp(rt);
     77 }
     78 */
     79 
     80 //区间求和
     81 int query(int L,int R,int l,int r,int rt){
     82     if(L<=l&&r<=R){
     83         return sum[rt];
     84     }
     85     int m=(l+r)>>1;
     86     int ret=0;
     87     if(L<=m)ret+=query(L,R,lson);
     88     if(R>m) ret+=query(L,R,rson);
     89     return ret;
     90 }
     91 
     92 /*
     93 //区间最值
     94 int query(int L,int R,int l,int r,int rt){
     95     if(L<=l&&r<=R){
     96         return MAX[rt];
     97     }
     98     int m=(l+r)>>1;
     99     int ret=0;
    100     if(L<=m)ret=max(ret,query(L,R,lson));
    101     if(R>m) ret=max(ret,query(L,R,rson));
    102     return ret;
    103 }
    104 */
    105 int x[maxn];
    106 int main(){
    107     int n;
    108     while(~scanf("%d",&n)){
    109         build(0,n-1,1);
    110         int sum=0;
    111         for(int i=0;i<n;i++){
    112             scanf("%d",&x[i]);
    113             sum+=query(x[i],n-1,0,n-1,1);
    114             update(x[i],0,n-1,1);
    115         }
    116         int ret=sum;
    117         for(int i=0;i<n;i++){
    118             sum+=n-x[i]-x[i]-1;
    119             ret=min(ret,sum);
    120         }
    121         printf("%d
    ",ret);
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    第一阶段:前端开发_使用JS完成注册页面表单校验完善
    第一阶段:前端开发_使用 JS 完成页面定时弹出广告
    第一阶段:前端开发_使用JS完成首页轮播图效果
    第一阶段:前端开发_使用JS完成注册页面表单校验
    三、Java基础工具(1)_常用类——日期类
    使MySQL支持emoji
    1. Two Sum [Array] [Easy]
    『IOS』 遇到问题记录(长期更新)
    [IOS] 详解图片局部拉伸 + 实现图片局部收缩
    【IOS】模仿"抽屉新热榜"动态启动页YFSplashScreen
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9729090.html
Copyright © 2011-2022 走看看