• hdu 2838 求逆序对


    1. /*****************************************************************************************************************
    2. 题意:给你N个排列不规则的数,任务是把它从小到大排好,每次只能交换相邻两个数,交换一次的代价为两数之和,求最小代价
    3. 注意 每次交换 都必须只能交换相邻的2个
    4. 思路:对于当前数X,我们如果知道前面比它大的数有多少,假设为K,那么有部分代价是确定的,那就是K*X;
    5. 然后还得加上比它大的那些数之和,这就是当数列到X为止,排好所需要的最小代价。
    6. **********************************************************************************************************************/
    7. #include<iostream>
    8. #include<cstring>
    9. using namespace std;
    10. const int maxn=100001;
    11. struct node
    12. {
    13. int cnt;
    14. __int64 sum;
    15. }tree[maxn];
    16. int n;
    17. int lowBit(int x)
    18. {
    19. return x&(-x);
    20. }
    21. void modify(int x,int y,int t)
    22. {
    23. while(x<=n)
    24. {
    25. tree[x].sum+=y;
    26. tree[x].cnt+=t; //tree[].cnt来保存是否出现过a
    27. x+=lowBit(x);
    28. }
    29. }
    30. __int64 query_cnt(int x) //比x小的数的个数
    31. {
    32. __int64 sum=0;
    33. while(x>0)
    34. {
    35. sum+=tree[x].cnt;
    36. x-=lowBit(x);
    37. }
    38. return sum;
    39. }
    40. __int64 query_sum(int x) //比x小的所有数之和
    41. {
    42. __int64 sum=0;
    43. while(x>0)
    44. {
    45. sum+=tree[x].sum;
    46. x-=lowBit(x);
    47. }
    48. return sum;
    49. }
    50. int main()
    51. {
    52. while(~scanf("%d",&n))
    53. {
    54. int a;
    55. __int64 ans=0;
    56. memset(tree,0,sizeof(tree));
    57. for(int i=1;i<=n;i++)
    58. {
    59. scanf("%d",&a);
    60. modify(a,a,1); //以a为下标更新数组
    61. __int64 k1=i-query_cnt(a); //k1为前i个数比a大的数的个数
    62. if(k1!=0)
    63. {
    64. __int64 k2=query_sum(n)-query_sum(a); //目前所有数的和-目前所有比a小的数的和,为比a大的数的和
    65. ans+=k1*a+k2; //调换a所需的时间
    66. }
    67. }
    68. printf("%I64d ",ans);
    69. }
    70. system("pause");
    71. return 0;
    72. }





    附件列表

    • 相关阅读:
      linux自动清理30天之前的文件
      Oracle树查询及相关函数
      jackson循环引用导致序列化stackOverFlow的解决
      java核心技术36讲笔记
      Quartz学习
      Quartz学习
      java核心技术36讲
      git常用命令
      CTCall简介(后续会继续补充)
      自定义导航栏,隐藏导航栏底部的灰色线条
    • 原文地址:https://www.cnblogs.com/sober-reflection/p/3d228fc2288e72e43b2fdeccb550286f.html
    Copyright © 2020-2023  润新知