zoukankan      html  css  js  c++  java
  • Cow Sorting

    hdoj 2838

    题目大意:给出数,求排成正序的最少时间,每两个数交换的时间是 两个数的值的和。

    解决:树状数组,只需求出 在这个数加入之前比这个数大的个数,然后更新,再求出这个数加入之前比这个数大的数的总和

    总共的代价是:cnt*加入的数+比这个数大的数的和

    #include <iostream>
    #include <functional>
    #include <algorithm>
    using namespace std;
    #define LL __int64
    const int N=100000;
    LL sum[N+5]; //第i个数前比数num[i]大的数的和 
    LL cnt[N+5]; //第i个数前比数num[i]大的数的个数
    inline int lowbit(int x)
    {
        return x&(-x);
    }
    
    void update(LL t[],int p,int delta)
    {
        for(int i=p;i>0;i-=lowbit(i))
           t[i]+=delta;
    }
    LL getsum(LL t[],int p)
    {
        LL tot=0;
        for(int i=p;i<=N;i+=lowbit(i))
          tot+=t[i];
        return tot;  
    }
    
    int main()
    {
           int n, t;
            scanf("%d",&n);
       
            LL ans=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&t);
               //注意这个tmp必须是LL长整型的
                LL tmp=getsum(cnt,t+1);
                update(cnt,t,1);
                //这个s必须是长整型的,就是这个地方错了好几次的。
                LL s=getsum(sum,t+1);
                update(sum,t,t);
                ans += tmp*t+s;
            }
            printf("%I64d\n",ans);
    
        system("pause");
        return 0;
    } 
    

  • 相关阅读:
    作业
    作业4
    作业1
    作业
    补交课堂作业
    补交最后一题
    第三次作业
    作业
    C语言 homework(4)
    C语言 homework (3)
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2193206.html
Copyright © 2011-2022 走看看