zoukankan      html  css  js  c++  java
  • hdu4911 简单树状数组

    题意:
         给你一串数字,然后给你最多进行k次交换(只能交换相邻的)问交换后的最小逆序数是多少。


    思路:

         首先要知道的一个就是给你一个序列,每次只能交换相邻的位置,把他交换成一个递增序列所需要的最少步数等于整个序列的逆序数,在转化到这个题目,我们只要求出个逆序数,然后输出逆序数 - k就行了,如果是负数输出0。


    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    #define N 100000 + 10
    
    using namespace std;
    
    typedef struct
    {
       int num ,id;
    }NODE;
    
    NODE node[N];
    
    __int64 num[N];
    int hash[N];
    int lowbit(int x)
    {
       return x & -x;
    }
    
    void update(int x ,__int64 a ,int n)
    {
       for(int i = x ;i <= n ;i += lowbit(i))
       num[i] += a;
    }
    
    __int64 find(int x)
    {
       __int64 sum = 0;
       for(int i = x ;i > 0 ;i -= lowbit(i))
       sum += num[i];
       return sum;
    }
    
    bool camp(NODE a ,NODE b)
    {
       return a.num < b.num;
    }
    
    int main ()
    {
       int n ,i ,a;
       __int64 m ,sum;
       while(~scanf("%d %I64d" ,&n ,&m))
       {
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%d" ,&node[i].num);
             node[i].id = i;
          }
          sort(node + 1 ,node + n + 1 ,camp);
          int t = 0;
          node[0].num = -1;
          for(i = 1 ;i <= n; i ++)
          {
             if(node[i].num != node[i-1].num)
             t ++;                         
             hash[node[i].id] = t;
          }
          memset(num ,0 ,sizeof(num));
          for(sum = 0 ,i = 1 ;i <= n ;i ++)
          {
             sum += (i - 1) - find(hash[i]);
             update(hash[i] ,1 ,t);
          }
          if(sum < m) printf("0
    ");
          else printf("%I64d
    " ,sum - m);
       }
       return 0;
    }
          
          
    

  • 相关阅读:
    mysql索引、group by、explain、insert delayed
    mysql学习笔记
    Handler
    文件操作
    RatingBar
    ListView(二)
    文件管理函数的草稿
    SAX解析XML
    phpunit
    Service(一)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062896.html
Copyright © 2011-2022 走看看