[关闭]
@2017libin 2019-06-16T16:54:28.000000Z 字数 952 阅读 48

树状数组

acm


  1. # include<iostream>
  2. # include<string>
  3. # include<algorithm>
  4. #include<numeric>
  5. #include <vector>
  6. #include <queue>
  7. using namespace std;
  8. int c[100];
  9. int b[100];
  10. int n;
  11. int lowbit(int i) {
  12. return i & (-i);
  13. }
  14. //初始化树状数组c[n]
  15. // c[n] = b[n-0]+b[n-1]+...b[n-(lowbit(i)-1)]
  16. void init() {
  17. for (int i = 1; i <= n; ++i) {
  18. int tmp = lowbit(i);
  19. for (int j = 0; j < tmp; ++j)
  20. c[i] += b[i - j];
  21. }
  22. }
  23. // sum(m):返回[1,m]的和
  24. // c[n]代表的是lowbit(n)个b数组元素的和
  25. // c[n] = b[n-0]+b[n-1]+...b[n-(lowbit(i)-1)]
  26. int Sum(int m) {
  27. int sum = 0;
  28. while (m > 0) {
  29. sum += c[m]; //加上lowbit[m]个元素的和
  30. m -= lowbit(m); //接着求剩下的 m - lowbit[m]个元素的和
  31. }
  32. return sum;
  33. }
  34. // 执行 b[p]+m
  35. //它的父节点都要加m
  36. void Plus(int p, int m) {
  37. while (p <= n) {
  38. c[p] += m;
  39. p += lowbit(p);
  40. }
  41. }
  42. //测试sum,plus函数
  43. int main1() {
  44. cin >> n;
  45. //这里数组下标从1开始
  46. for (int i = 1; i <= n; i++)
  47. cin >> b[i];
  48. init();
  49. cout << Sum(4);
  50. system("pause");
  51. return 0;
  52. }
  53. int main() {
  54. int at[100];
  55. cin >> n;
  56. for (int i = 1; i <= n; ++i)
  57. cin >> b[i];
  58. for (int i = 1; i <= n; ++i)
  59. at[b[i]] = i;
  60. int num = 0;
  61. for (int i = n; i >= 1; --i) {
  62. int index = at[i];
  63. num += Sum(index - 1); //统计左边有多少个数,左边的数肯定比当前数大,因为是由大到小依次填入数组
  64. Plus(index,1);
  65. }
  66. cout << num;
  67. system("pause");
  68. return 0;
  69. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注