当前位置:   article > 正文

BZOJ4627: [BeiJing2016]回转寿司

回转寿司 离散化 线段树

这题调了一晚上快调死了= = 

此题看着很奇怪,我们先搞一搞式子看看它到底要我们求什么

大概是 ∑ni=1 [L <= Σkj=i a_i <= R] (k >= i)

发现这可以转成前缀和的形式

就是 ∑ni=1 [L <= s[k] - s[j] <= R] (i <= j <= k)

发现它就是求对于每一个 s[k] 满足 s[j] ∈ [s[k] - R, s[k] - L] 的 s[j] 个数

可以权值线段树区间求和搞啊!

然后就是一个裸的线段树了

二分和离散化总容易出一些奇怪的小锅


代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<cctype>
  6. #include<cstdio>
  7. #define lson (x << 1)
  8. #define rson ((x << 1) | 1)
  9. using namespace std;
  10. typedef long long ll;
  11. const int MAXN = 100005;
  12. struct Node{
  13. ll sum;
  14. }t[(MAXN * 3) << 2];
  15. int n, sizb, rnk[MAXN];
  16. ll lll, rrr, res;
  17. ll num[MAXN], uni[MAXN * 3];
  18. inline void pushup(int x) {
  19. t[x].sum = t[lson].sum + t[rson].sum;
  20. return;
  21. }
  22. void update(int dst, int l, int r, int x) {
  23. if(l == r) {
  24. ++t[x].sum;
  25. return;
  26. }
  27. int mid = ((l + r) >> 1);
  28. if(dst <= mid) update(dst, l, mid, lson);
  29. else update(dst, mid + 1, r, rson);
  30. pushup(x);
  31. return;
  32. }
  33. ll query(int L, int R, int l, int r, int x) {
  34. if(L > R) return 0ll;
  35. if(L <= l && r <= R) {
  36. return t[x].sum;
  37. }
  38. int mid = ((l + r) >> 1);
  39. ll ans = 0ll;
  40. if(L <= mid) ans = query(L, R, l, mid, lson);
  41. if(mid < R) ans += query(L, R, mid + 1, r, rson);
  42. return ans;
  43. }
  44. inline int lower(int l, int r, ll val, ll *arr) {
  45. register int mid;
  46. while(l < r) {
  47. mid = ((l + r) >> 1);
  48. if(arr[mid] >= val) r = mid;
  49. else l = mid + 1;
  50. }
  51. return l;
  52. }
  53. inline int upper(int l, int r, ll val, ll *arr) {
  54. register int mid;
  55. while(l < r) {
  56. mid = ((l + r + 1) >> 1);
  57. if(arr[mid] <= val) l = mid;
  58. else r = mid - 1;
  59. }
  60. return l;
  61. }
  62. int main() {
  63. scanf("%d%lld%lld", &n, &lll, &rrr);
  64. uni[++sizb] = 0ll;
  65. register ll pres = 0ll;
  66. for(int i = 1; i <= n; ++i) {
  67. scanf("%lld", &num[i]);
  68. pres += num[i];
  69. uni[++sizb] = pres;
  70. uni[++sizb] = pres - rrr;
  71. uni[++sizb] = pres - lll;
  72. }
  73. sort(uni + 1, uni + sizb + 1);
  74. sizb = unique(uni + 1, uni + sizb + 1) - uni - 1;
  75. pres = 0ll;
  76. for(int i = 1; i <= n; ++i) {
  77. pres += num[i];
  78. rnk[i] = lower_bound(uni + 1, uni + sizb + 1, pres) - uni;
  79. }
  80. update(lower_bound(uni + 1, uni + sizb + 1, 0) - uni, 1, sizb, 1);
  81. pres = 0ll;
  82. for(int i = 1; i <= n; ++i) {
  83. pres += num[i];
  84. int lef = lower(1, sizb, pres - rrr, uni), rig = upper(1, sizb, pres - lll, uni);
  85. res += query(lef, rig, 1, sizb, 1);
  86. update(rnk[i], 1, sizb, 1);
  87. }
  88. printf("%lld\n", res);
  89. return 0;
  90. }

  

 

转载于:https://www.cnblogs.com/xcysblog/p/9617141.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/622338
推荐阅读
相关标签
  

闽ICP备14008679号