传送门

首先如果起点终点都在同一侧可以直接处理,如果需要过桥答案再加1

对于k等于1的情况

桥的坐标为x的话,a和b为起点和终点坐标

$ans=\sum_{1}^{n} abs(a_{i}-x)+abs(b_{i}-x)$

起点和终点显然可以合并

那么 $ans=\sum_{1}^{n} abs(a_{i}-x)$

x为中位数就是最优解

对于k等于2的情况

首先有个结论:$(a_{i}+b_{i})/2$ 离哪座桥近,就选择哪座桥

可以把坐标按照上面的公式排序,然后枚举中间点,分成左右两部分

每一部分都有一座桥,那么就需要一个可以维护中位数,求和,删除/增加一个数的数据结构

平衡树或者线段树都可以

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #define N 200100
  6. #define LL long long
  7. #define root 1, 1, cnt
  8. #define ls now << 1, l, mid
  9. #define rs now << 1 | 1, mid + 1, r
  10.  
  11. using namespace std;
  12.  
  13. int k, n, m, cnt;
  14. LL ans, tmp, tot, L[2], R[2];
  15. int a[N];
  16. char s[2];
  17.  
  18. struct node
  19. {
  20. int x, y;
  21. }p[N];
  22.  
  23. struct tree
  24. {
  25. LL sum[N << 2], num[N << 2];
  26. inline void update(int now, int l, int r, int x, int d)
  27. {
  28. num[now] += d, sum[now] += d * a[x];
  29. if(l == r) return;
  30. int mid = (l + r) >> 1;
  31. if(x <= mid) update(ls, x, d);
  32. else update(rs, x, d);
  33. }
  34. inline int find(int now, int l, int r, int x)
  35. {
  36. if(l == r)
  37. {
  38. L[0] += sum[now], L[1] += num[now];
  39. return a[l];
  40. }
  41. int mid = (l + r) >> 1;
  42. if(num[now << 1] >= x)
  43. {
  44. R[0] += sum[now << 1 | 1], R[1] += num[now << 1 | 1];
  45. return find(ls, x);
  46. }
  47. else
  48. {
  49. L[0] += sum[now << 1], L[1] += num[now << 1];
  50. return find(rs, x - num[now << 1]);
  51. }
  52. }
  53. }t[2];
  54.  
  55. inline int read()
  56. {
  57. int x = 0, f = 1;
  58. char ch = getchar();
  59. for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
  60. for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
  61. return x * f;
  62. }
  63.  
  64. inline void solve1()
  65. {
  66. int i, x;
  67. for(i = 1; i <= n; i++)
  68. {
  69. scanf("%s", s), a[++m] = read();
  70. scanf("%s", s + 1), a[++m] = read();
  71. if(s[0] == s[1]) ans += abs(a[m] - a[m - 1]), m -= 2;
  72. else ans++;
  73. }
  74. sort(a + 1, a + m + 1);
  75. x = a[m >> 1];
  76. for(i = 1; i <= m; i++) ans += abs(a[i] - x);
  77. }
  78.  
  79. inline bool cmp(node x, node y)
  80. {
  81. return x.x + x.y < y.x + y.y;
  82. }
  83.  
  84. inline void solve2()
  85. {
  86. int i, x;
  87. for(i = 1; i <= n; i++)
  88. {
  89. m++;
  90. scanf("%s", s), p[m].x = read();
  91. scanf("%s", s + 1), p[m].y = read();
  92. if(s[0] == s[1]) tot += abs(p[m].x - p[m].y), m--;
  93. else tot++;
  94. }
  95. if(!m)
  96. {
  97. ans = tot; return;
  98. }
  99. sort(p + 1, p + m + 1, cmp);
  100. for(i = 1; i <= m; i++) a[++cnt] = p[i].x, a[++cnt] = p[i].y;
  101. sort(a + 1, a + cnt + 1);
  102. cnt = unique(a + 1, a + cnt + 1) - a - 1;
  103. for(i = 1; i <= m; i++)
  104. p[i].x = lower_bound(a + 1, a + cnt + 1, p[i].x) - a,
  105. p[i].y = lower_bound(a + 1, a + cnt + 1, p[i].y) - a;
  106. for(i = 1; i <= m; i++)
  107. t[1].update(root, p[i].x, 1), t[1].update(root, p[i].y, 1);
  108. x = t[1].find(root, m);
  109. ans = x * L[1] - L[0] + R[0] - x * R[1] + tot;
  110. for(i = 1; i <= m; i++)
  111. {
  112. t[0].update(root, p[i].x, 1), t[0].update(root, p[i].y, 1);
  113. t[1].update(root, p[i].x, -1), t[1].update(root, p[i].y, -1);
  114. tmp = L[0] = L[1] = R[0] = R[1] = 0;
  115. x = t[0].find(root, i);
  116. tmp += x * L[1] - L[0] + R[0] - x * R[1];
  117. L[0] = L[1] = R[0] = R[1] = 0;
  118. x = t[1].find(root, m - i);
  119. tmp += x * L[1] - L[0] + R[0] - x * R[1];
  120. ans = min(ans, tmp + tot);
  121. }
  122. }
  123.  
  124. int main()
  125. {
  126. k = read();
  127. n = read();
  128. if(k == 1) solve1();
  129. if(k == 2) solve2();
  130. printf("%lld\n", ans);
  131. return 0;
  132. }

  

[luoguP3644] [APIO2015]八邻旁之桥(权值线段树)的更多相关文章

  1. 题解【luoguP3644 [APIO2015]八邻旁之桥】

    题目链接 题解 家和公司在同侧 简单,直接预处理掉 若 \(k=1\) 取所有的居民的\(\frac{家坐标+公司坐标}{2}\)的所有坐标的正中间建一座桥,使所有居民到的距离最小. 实现方法:线段树 ...

  2. 洛谷 P3644 [APIO2015]八邻旁之桥 解题报告

    P3644 [APIO2015]八邻旁之桥 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好\(1000000001\)栋的建筑 ...

  3. [APIO2015]八邻旁之桥——非旋转treap

    题目链接: [APIO2015]八邻旁之桥 对于$k=1$的情况: 对于起点和终点在同侧的直接计入答案:对于不在同侧的,可以发现答案就是所有点坐标与桥坐标的差之和+起点与终点不在同一侧的人数. 将所有 ...

  4. [BZOJ4071][APIO2015]八邻旁之桥

    BZOJ(这题是BZOJ权限题,有权限号的就去看看吧) Luogu(良心洛谷) 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好 ...

  5. APIO2015 八邻旁之桥/巴邻旁之桥

    题目描述: bz luogu 题解: 贪心+权值线段树. $K=1$的时候,答案为$\sum |x-l| + |x-r|$,所以所有端点排序后取中位数即可. $K=2$的时候,一定是左边的一些走左边的 ...

  6. [APIO2015]八邻旁之桥

    题面在这里 sol 这是一个\(Splay\)的题解 首先,如果一个人的家和办公室在同一侧,我们可以直接预处理; 如果不在同一侧,也可以加上1(当然要过桥啦) 当k==1时 我们设桥的位置为\(pos ...

  7. 洛谷 P3644 [APIO2015]八邻旁之桥(对顶堆维护中位数)

    题面传送门 题意: 一条河将大地分为 \(A,B\) 两个部分.两部分均可视为一根数轴. 有 \(n\) 名工人,第 \(i\) 名的家在 \(x_i\) 区域的 \(a_i\) 位置,公司在 \(y ...

  8. 【BZOJ4071】八邻旁之桥(线段树)

    [BZOJ4071]八邻旁之桥(线段树) 题面 BZOJ权限题,洛谷链接 题解 既然\(k<=2\) 那么,突破口就在这里 分类讨论 ①\(k=1\) 这...不就是中位数吗.... 直接把所有 ...

  9. 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap

    [BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...

随机推荐

  1. nodejs--http

    http模块主要用到四个方法: 1.Server类 const http = require('http'); let server = new Server(); server.on('reques ...

  2. Java源码解析——集合框架(二)——ArrayBlockingQueue

    ArrayBlockingQueue源码解析 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection ...

  3. 什么是mysql数据库安全 简单又通俗的mysql库安全简介

    首先我们要了解一下什么是mysql数据库,mysql是目前网站以及APP应用上用的较多的一个开源的关系型数据库系统,可以对数据进行保存,分段化的数据保存,也可以对其数据进行检索,查询等功能的数据库. ...

  4. 来自一个大三开学三周的huster的迷茫与失措

    大三开学考研保研的话题开始多了起来.自从前天去听了一回谢长生教授的实验室宣讲会,回来直到现在都好像心头上压了些东西,喘不过气来.本来我就少与外界接触,加之我自己一个人主动学习的积极性也很是缺乏,所以当 ...

  5. JavaSE基础复习---2---2018/9/28

    目录: 1.数据类型 2.变量 3.数组 1.数据类型 谈到java的数据类型,必须知道java是强类型语言.首先,每个变量有类型,每个表达式有类型,而且每种类型是严格定义的.其次,所有的数值传递,不 ...

  6. JAVA 反射之Method

    ★ Method没有构造器,只能通过Class获取. 重点方法: class.getDeclaredMethods():获取所有方法. class.getDeclaredMethod(String n ...

  7. (数据科学学习手札36)tensorflow实现MLP

    一.简介 我们在前面的数据科学学习手札34中也介绍过,作为最典型的神经网络,多层感知机(MLP)结构简单且规则,并且在隐层设计的足够完善时,可以拟合任意连续函数,而除了利用前面介绍的sklearn.n ...

  8. Eclipse_安装SAP_HANA数据库插件

    1.对于Eclipse Oxygen,请添加URL https://tools.hana.ondemand.com/oxygen 2.对于Eclipse luna,请添加URL     https:/ ...

  9. Delphi中Templates代码模板添加注意事项

    今天用Delphi中的代码模板添加一段代码,结果就是有问题,多次测试后,发现是编码需要注意. <?xml version="1.0" encoding="GB231 ...

  10. C++11中default的使用

    In C++11, defaulted and deleted functions give you explicit control over whether the special member ...