zoukankan      html  css  js  c++  java
  • hdu2838Cow Sorting(树状数组+逆序数)

    题目链接:点击打开链接

    题意描写叙述:给定一个长度为100000的数组,每一个元素范围在1~100000,且互不同样,交换当中的随意两个数须要花费的代价为两个数之和。

    问怎样交换使数组有序。花费的代价最小?

    解题思路:

    1、显然我们知道,要使一个数组有序至少交换的次数(即必需要交换的次数)为数组中的逆序数

    2、因为数组的长度比較大所以我们能够通过树状数组来统计结果

    此处须要两个树状数组

    第一个:记录小于等于某个值的元素的个数

    第二个:记录小于等于某个值的元素的和


    代码:

    #include <cstdio>
    #include <cstring>
    #define MAXN 100010
    using namespace std;
    int C[MAXN];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    int sum(int pos)
    {
        int ret=0;
        while(pos>0)
        {
            ret+=C[pos];
            pos-=lowbit(pos);
        }
        return ret;
    }
    void add(int pos,int v)
    {
        while(pos<=100000)
        {
            C[pos]+=v;
            pos+=lowbit(pos);
        }
    }
    long long Ct[MAXN];
    long long sumt(int pos)
    {
        long long ret=0;
        while(pos>0)
        {
            ret+=Ct[pos];
            pos-=lowbit(pos);
        }
        return ret;
    }
    void addt(int pos,int v)
    {
        while(pos<=100000)
        {
            Ct[pos]+=v;
            pos+=lowbit(pos);
        }
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            memset(C,0,sizeof(C));
            memset(Ct,0,sizeof(Ct));
            long long ans=0;
            int x;
            for(int i=0; i<n; ++i)
            {
                scanf("%d",&x);
                add(x,1);
                addt(x,x);
                ans+=((sum(100000)-sum(x))*(long long)x+sumt(100000)-sumt(x));///注意溢出问题
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    



  • 相关阅读:
    leetcode每日刷题计划-简单篇day10
    leetcode每日刷题计划-简单篇day9
    leetcode每日刷题计划-简单篇day8
    leetcode每日刷题计划-简单篇day7
    leetcode每日刷题计划-简单篇day6
    leetcode每日刷题计划-简单篇day5
    leetcode每日刷题计划-简单篇day4
    leetcode每日刷题计划-简单篇day3
    设计模式解决 if-else
    线程池
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7066759.html
Copyright © 2011-2022 走看看