题意:在区间中找一个数,求出该区间每个数与这个数距离的总和,使其最小

找的数字是中位数(若是偶数个,则中间随便哪个都可)接着找到该区间比此数大的数的总和

区间中位数可以使用划分树,然后在其中记录:每层的 1-i 中划分到左区间的总和

划分树:

划分树是一种基于线段树的数据结构。主要用于快速求出(在log(n)的时间复杂度内)序列区间的第k大值 。

划分树和归并树都是用线段树作为辅助的,原理是基于快排 和归并排序 的。

划分树的建树过程基本就是模拟快排过程,取一个已经排过序的区间中值,然后把小于中值的点放左边,大于的放右边。并且记录d层第i个数之前(包括i)小于中值的放在左边的数。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. #define dir(a,b) (a>>b)
  6. const int Max=1e5+;
  7. int orval[Max];
  8. int dsegtr[][Max];//记录第i层划分树的序列
  9. int lele[][Max];//记录第i层的1-i划分到左子树的元素个数(包括i)
  10. long long sum[][Max],psum[Max],lsum;//每层的1-i中划分到左区间的总和
  11. void Create(int sta,int enn,int cur)
  12. {
  13. int mid=dir(sta+enn,);
  14. int lsame=mid-sta+;//此区间左边不小于orval[mid]的个数
  15. int lsta=sta,rsta=mid+;
  16. for(int i=sta; i<=mid; ++i)
  17. {
  18. if(orval[i]<orval[mid])
  19. lsame--;
  20. }
  21. for(int i=sta; i<=enn; ++i)//给下一层赋值
  22. {
  23. sum[cur][i]=sum[cur][i-];
  24. if(i==sta)
  25. {
  26. lele[cur][i]=;//表示[l, i]内有多少个数分到左边
  27. }
  28. else
  29. {
  30. lele[cur][i]=lele[cur][i-];
  31.  
  32. }
  33. if(dsegtr[cur][i]==orval[mid])
  34. {
  35. if(lsame)
  36. {
  37. sum[cur][i]+=dsegtr[cur][i];
  38. lsame--;
  39. lele[cur][i]++;
  40. dsegtr[cur+][lsta++]=dsegtr[cur][i];//相当于移动元素到左边
  41. }
  42. else
  43. {
  44. dsegtr[cur+][rsta++]=dsegtr[cur][i];//相当于移动元素到右边
  45. }
  46. }
  47. else if(dsegtr[cur][i]<orval[mid])
  48. {
  49. sum[cur][i]+=dsegtr[cur][i];
  50. lele[cur][i]++;
  51. dsegtr[cur+][lsta++]=dsegtr[cur][i];
  52. }
  53. else
  54. {
  55. dsegtr[cur+][rsta++]=dsegtr[cur][i];
  56. }
  57. }
  58. if(sta==enn)
  59. return;
  60. Create(sta,mid,cur+);
  61. Create(mid+,enn,cur+);
  62. return;
  63. }
  64. int Query(int sta,int enn,int cur,int lef,int rig,int k)
  65. {
  66. int lsame;//[sta, lef)内将被划分到左子树的元素数目
  67. int rsame;//[lef,rig]内将被划分到左子树的元素数目 关键
  68. int mid=dir(sta+enn,);
  69. if(sta==enn)
  70. return dsegtr[cur][sta];
  71. if(sta==lef)//特判
  72. {
  73. lsame=;
  74. rsame=lele[cur][rig];
  75. }
  76. else
  77. {
  78. lsame=lele[cur][lef-];
  79. rsame=lele[cur][rig]-lsame;
  80. }
  81. if(k<=rsame)
  82. {
  83. return Query(sta,mid,cur+,sta+lsame,sta+lsame+rsame-,k);//关键
  84. }
  85. else
  86. {
  87. lsum+=sum[cur][rig]-sum[cur][lef-];//所求值不在左区间
  88. return Query(mid+,enn,cur+,mid-sta++lef-lsame,mid-sta++rig-lsame-rsame,k-rsame);//关键
  89. }
  90. }
  91. long long Solve(long long temp,int rig,int lef,int k)
  92. {
  93. long long resr=psum[rig]-psum[lef-]-lsum-temp-(long long)(rig-lef+-k)*temp;
  94. long long resl=(long long)(k-)*temp-lsum;
  95. return resr+resl;
  96. }
  97. int main()
  98. {
  99. int n,m,t,coun=;
  100. int lef,rig;
  101. scanf("%d",&t);
  102. while(t--)
  103. {
  104. scanf("%d",&n);
  105. for(int i=;i<;++i)
  106. sum[i][]=0ll;
  107. psum[]=0ll;
  108. for(int i=; i<=n; ++i)
  109. {
  110. scanf("%d",&orval[i]);
  111. psum[i]=psum[i-]+orval[i];
  112. dsegtr[][i]=orval[i];
  113. sum[][i]=sum[][i-]+orval[i];
  114. }
  115. sort(orval+,orval+n+);
  116. Create(,n,);
  117. scanf("%d",&m);
  118. printf("Case #%d:\n",++coun);
  119. for(int i=; i<m; ++i)
  120. {
  121. lsum=0ll;
  122. scanf("%d %d",&lef,&rig);
  123. lef++,rig++;
  124. int temp=Query(,n,,lef,rig,(rig-lef+>>));
  125. printf("%I64d\n",Solve(temp,rig,lef,(rig-lef+>>)));
  126. }
  127. printf("\n");
  128. }
  129. return ;
  130. }

参考:http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html

HDU 3473 Minimum Sum (划分树求区间第k大带求和)(转)的更多相关文章

  1. [hdu2665]Kth number(划分树求区间第k大)

    解题关键:划分树模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cs ...

  2. HDU 3473 Minimum Sum 划分树,数据结构 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...

  3. HDU 3473 Minimum Sum 划分树

    题意: 给出一个长度为\(n(1 \leq n \leq 10^5)\)的序列\(a\) 有若干次查询l r:找到一个\(x\)使得\(\sum \limits_{l \leq i \leq r} \ ...

  4. [csu/coj 1080]划分树求区间前k大数和

    题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...

  5. HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. [poj2104]kth-number(归并树求区间第k大)

    复杂度:$O(nlog^3n)$ #include<cstdio> #include<cstring> #include<algorithm> #include&l ...

  7. poj 2104 主席树(区间第k大)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44940   Accepted: 14946 Ca ...

  8. POJ2761---Feed the dogs (Treap求区间第k大)

    题意 就是求区间第k大,区间 不互相包含. 尝试用treap解决一下 第k大的问题. #include <set> #include <map> #include <cm ...

  9. HDU 3473 Minimum Sum (划分树)

    题意:给定一个数组,有Q次的询问,每次询问的格式为(l,r),表示求区间中一个数x,使得sum = sigma|x - xi|最小(i在[l,r]之间),输出最小的sum. 思路:本题一定是要O(nl ...

随机推荐

  1. iOS-ASIHTTPRequest框架学习

    本文转载至 http://www.cnblogs.com/A-Long-Way-Chris/p/3539679.html 前段时间在公司的产品中支持了够快网盘,用于云盘存储. 在这个过程中,学习到了很 ...

  2. knockoutJs在移动设备上有时无法更新控件值

    最近在用cordova(phonegap)写一个移动app,表单比较复杂,用了knockoutJs作为前端的MVVM框架进行数据绑定. 但是发现有时候(其实是每次)如果最后在input中编辑一个值,然 ...

  3. 子单元通过 prop 接口与父单元进行了良好的解耦

    https://cn.vuejs.org/v2/guide/#起步 现在,我们可以使用 v-bind 指令将待办项传到循环输出的每个组件中: <div id="app-7"& ...

  4. VS2015 如何打印出 类的内存布局?

    项目->属性->C/C++->命令行 添加如下内容: /d1 reportAllClassLayout [XXX] XXX 可选,代表源文件名,例如 main.cpp 或 /d1 r ...

  5. 使用Sentry集中化日志管理

    在调试程序中,通过日志分期来排查BUG是一个重要手段,它可以说是程序调试的利器. 关于日志管理 随着应用组件变多,那么各coder对输出日志五花八门,有写入stdout,有写stderr, 有写到sy ...

  6. 解决Vue的表格中,expand只有某些行需要展开的问题。

    element UI里的表格里,type="expand"的话,所有行都有展开的选项,然而实际中有些行根据判断不需要展开,而element目前对这个问题还不是很友好,现在有个可以通 ...

  7. python并发编程&IO模型

    一 IO模型介绍 为了更好地了解IO模型,可先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(n ...

  8. ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据

    下载地址:https://www.apexsql.com/download.aspx 如何从意外UPDATE和DELETE操作中恢复SQL Server数据 ApexSQL Log 从意外UPDATE ...

  9. ApexSQL Recover 恢复一个被drop的表的数据

    没有备份的情况下恢复一个被drop的表的数据 ApexSQL Recover 恢复一个被drop的表的数据 转自:https://solutioncenter.apexsql.com/zh/%E6%B ...

  10. SUBMIT RM07DOCS【MB51】 获取返回清单,抓取标准报表数据

    *&---------------------------------------------------------------------* *& Report YT_SUBMIT ...