zoukankan      html  css  js  c++  java
  • HDU 2838 (树状数组求逆序数)


    题意:

    给你N个排列不规则的数(1~N),任务是把它从小到大排好,每次仅仅能交换相邻两个数,交换一次的代价为两数之和。求最小代价



    思路:对于当前数X。我们如果知道前面比它大的数有多少,如果为K,那么有部分代价是确定的,那就是K*X。然后还得加上比它大的那些数之和,这就是当数列到X为止,排好所须要的最小代价。



    #include <stdio.h>  
    #include <iostream>  
    #include <algorithm>  
    #include <string.h>  
    #include <math.h>  
    #define M 100005  
    #define LL __int64  
    using namespace std;  
     
    struct node
    {
    	LL sum;
    	int id;
    }c[M];
    int n;  
    int Lowbit(int x)  
    {  
        return x&(-x);  
    }  
      
    void Update(int x,int k,int num)  
    {  
        while(x<=n)  
        {  
            c[x].id +=k;
    		c[x].sum +=num;
            x+=Lowbit(x);  
        }  
    }  
      
    LL getSum(int x)  
    {  
        LL sum=0;  
        while(x>0)  
        {  
            sum+=c[x].sum;  
            x-=Lowbit(x);  
        }  
        return sum;  
    }  
      
    int getNum(int x)  
    {  
    	int sum=0;  
        while(x>0)  
        {  
            sum+=c[x].id;  
            x-=Lowbit(x);  
        }  
        return sum;  
    }  
    int main()  
    {  
        while(~scanf("%d",&n)) 
        {  
    		int x;
            memset(c,0,sizeof(c));
    		LL ans=0,k;
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&x);
                Update(x,1,x);  
                LL k=(i-getNum(x));  
    			if(k==0)
    				continue;
    			ans+=(k*x+getSum(n)-getSum(x));
            }  
            printf("%I64d
    ",ans);  
        }  
        return 0;  
    }  
    /*
    4
    3
    2
    4
    1
    
    
    17
    */


  • 相关阅读:
    07:常识性问题
    知识梳理
    Linux之防火墙iptables
    centos常用命令
    Centos7 内核升级及删除无用内核
    Java线程之Callable、Future
    Java线程之Timer
    Java线程之ThreadLocal
    Java线程之synchronized
    Java线程之wait()、notify()、notifyAll()
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7093670.html
Copyright © 2011-2022 走看看