当前位置:   article > 正文

bzoj 4627:[BeiJing2016]回转寿司_回转寿司 算法

回转寿司 算法

算法:裸树状数组/裸线段树 

难度:(NOIP-)

  1. 设s[i]为前缀和,差分,把序列和转化为前缀相减,即选出满足L≤s[x]−s[y]≤R的x>y的数个数。
  2. 那么我们枚举x,即可得到y的范围,二分找以前的满足条件的yy的个数(lowerbound&&upper_bound)。可以维护1到当前位置树状数组,在树状数组中查询个数,最后再将该数加入到树状数组中。但是数据范围大,所以需要离散化。
  3. 时间复杂度O(nlogn)

代码如下:

  1. //不开long long 见祖宗!
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <cstdlib>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <queue>
  9. #define ll long long
  10. #define N 100005
  11. using namespace std;
  12. ll a[N],sum[N],c[N];
  13. ll n,l,r;
  14. int lowbit(int x)
  15. {
  16. return x & (-x);
  17. }
  18. void add(int x)
  19. {
  20. while(x<=n)
  21. {
  22. c[x]++;
  23. x+=lowbit(x);
  24. }
  25. }
  26. int query(int x)
  27. {
  28. int ret=0;
  29. while(x)
  30. {
  31. ret+=c[x];
  32. x-=lowbit(x);
  33. }
  34. return ret;
  35. }
  36. int main()
  37. {
  38. scanf("%lld%lld%lld",&n,&l,&r);
  39. for(int i = 1;i <= n;i++)
  40. {
  41. scanf("%lld",&a[i]);
  42. sum[i]=sum[i-1]+a[i];
  43. a[i]=sum[i];
  44. }
  45. sort(a+1,a+n+2);//多加一个sum[0],防止lowerbound时,数组越界。
  46. ll ans=0;
  47. for(ll i = 0;i <= n;i++)
  48. {
  49. ans+=query(upper_bound(a+1,a+n+2,sum[i]-l)-a-1)-query(lower_bound(a+1,a+n+2,sum[i]-r)-a-1);
  50. add(lower_bound(a+1,a+n+2,sum[i])-a);
  51. }
  52. printf("%lld\n",ans);
  53. return 0 ;
  54. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/622342
推荐阅读
相关标签
  

闽ICP备14008679号