https://www.lydsy.com/JudgeOnline/problem.php?id=4627

题意:求序列中和在L到R之间的字串种数。

要求的是和的范围,我们可以考虑先求一个前缀和pre,然后每个点j的贡献就是L <= pre[j] - pre[i] <= R(i < j)的i的种数了,移项一下变成

pre[j] - R <= pre[i] <= pre[j] - L

我们就可以考虑做个权值线段树维护一下所有pre,每次求贡献的时候做一个区间查询就可以了。

注意点:

1.由于范围太大又有负数,线段树要动态开点。

2.开局要加一个pre[0] = 0的前缀和

3.线段树里不必要开的点尽量不开否则可能由于空间WA

  1. #include <map>
  2. #include <set>
  3. #include <ctime>
  4. #include <cmath>
  5. #include <queue>
  6. #include <stack>
  7. #include <vector>
  8. #include <string>
  9. #include <cstdio>
  10. #include <cstdlib>
  11. #include <cstring>
  12. #include <sstream>
  13. #include <iostream>
  14. #include <algorithm>
  15. #include <functional>
  16. using namespace std;
  17. #define For(i, x, y) for(int i=x;i<=y;i++)
  18. #define _For(i, x, y) for(int i=x;i>=y;i--)
  19. #define Mem(f, x) memset(f,x,sizeof(f))
  20. #define Sca(x) scanf("%d", &x)
  21. #define Sca2(x,y) scanf("%d%d",&x,&y)
  22. #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
  23. #define Scl(x) scanf("%lld",&x);
  24. #define Pri(x) printf("%d\n", x)
  25. #define Prl(x) printf("%lld\n",x);
  26. #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
  27. #define LL long long
  28. #define ULL unsigned long long
  29. #define mp make_pair
  30. #define PII pair<int,int>
  31. #define PIL pair<int,long long>
  32. #define PLL pair<long long,long long>
  33. #define pb push_back
  34. #define fi first
  35. #define se second
  36. typedef vector<int> VI;
  37. int read(){int x = ,f = ;char c = getchar();while (c<'' || c>''){if (c == '-') f = -;c = getchar();}
  38. while (c >= ''&&c <= ''){x = x * + c - '';c = getchar();}return x*f;}
  39. const double eps = 1e-;
  40. const int maxn = 1e5 + ;
  41. const LL INF = 1e10 + 2e9;
  42. const int mod = 1e9 + ;
  43. int N,M,K;
  44. LL L,R;
  45. struct Tree{
  46. LL sum;
  47. int lt,rt;
  48. void init(){lt = rt = sum = ;}
  49. }tree[maxn * ];
  50. int tot;
  51. void check(int &t){
  52. if(t) return;
  53. t = ++tot;
  54. tree[t].init();
  55. }
  56. void Pushup(int &t){
  57. int ls = tree[t].lt,rs = tree[t].rt;
  58. tree[t].sum = tree[ls].sum + tree[rs].sum;
  59. }
  60. void update(int &t,LL l,LL r,LL x){
  61. check(t);
  62. if(l == r){
  63. tree[t].sum++;
  64. return;
  65. }
  66. LL m = l + r >> ;
  67. if(x <= m) update(tree[t].lt,l,m,x);
  68. else update(tree[t].rt,m + ,r,x);
  69. Pushup(t);
  70. }
  71. LL query(int &t,LL l,LL r,LL ql,LL qr){
  72. if(!t) return ;
  73. if(ql <= l && r <= qr) return tree[t].sum;
  74. LL m = l + r >> ;
  75. if(qr <= m) return query(tree[t].lt,l,m,ql,qr);
  76. else if(ql > m) return query(tree[t].rt,m + ,r,ql,qr);
  77. else return query(tree[t].lt,l,m,ql,m) + query(tree[t].rt,m + ,r,m + ,qr);
  78. }
  79. LL pre[maxn];
  80. int main(){
  81. N = read(); L = read(); R = read(); // sum[j] - L >= sum[i - 1] >= sum[j] - R;
  82. for(int i = ; i <= N; i ++) pre[i] = read() + pre[i - ];
  83. LL ans = ;
  84. int root = ;
  85. update(root,-INF,INF,);
  86. for(int i = ; i <= N ; i ++){
  87. if(pre[i] - R <= pre[i] - L) ans += query(root,-INF,INF,pre[i] - R,pre[i] - L);
  88. update(root,-INF,INF,pre[i]);
  89. }
  90. Prl(ans);
  91. return ;
  92. }

BZOJ4627 前缀和 + 权值线段树的更多相关文章

  1. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  2. bzoj 4627: [BeiJing2016]回转寿司 -- 权值线段树

    4627: [BeiJing2016]回转寿司 Time Limit: 10 Sec  Memory Limit: 256 MB Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店. ...

  3. HDU 6464 免费送气球 【权值线段树】(广东工业大学第十四届程序设计竞赛)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6464 免费送气球 Time Limit: 2000/1000 MS (Java/Others)    M ...

  4. hdu 5592 ZYB's Premutation (权值线段树)

    最近在线段树的世界里遨游,什么都能用线段树做,这不又一道权值线段树了么. ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  5. 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树

    题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...

  6. 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树

    [BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...

  7. HDU 6464 /// 权值线段树

    题目大意: 共Q次操作 操作有两种 操作一 在序列尾部加入f[i]个s[i] 操作二 查询序列第f[i]小到第s[i]小之间的总和 离线操作 把序列内的值离散化 然后利用离散化后的值 在线段树上对应权 ...

  8. 2019杭电多校第三场hdu6606 Distribution of books(二分答案+dp+权值线段树)

    Distribution of books 题目传送门 解题思路 求最大值的最小值,可以想到用二分答案. 对于二分出的每个mid,要找到是否存在前缀可以份为小于等于mid的k份.先求出这n个数的前缀和 ...

  9. P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)

    题意:带修求区间k小 题解:回忆在使用主席树求区间k小时 利用前缀和的思想 既然是前缀和 那么我们可以使用更擅长维护前缀和的树状数组 但是这里每一颗权值线段树就不是带版本的 而是维护数组里i号点的权值 ...

随机推荐

  1. Web API 2 自定义默认Identity Table Name

    One of the first issues you will likely encounter when getting started with ASP.NET Identity centers ...

  2. P1091 合唱队形 最长上升子序列

    思路:最长上升子序列 正着做一遍 倒着做一遍 然后 取最大值 #include<bits/stdc++.h> using namespace std; const int maxn=105 ...

  3. 大学jsp实验6session

    1.session对象的使用 (1)设计一个简单的在线问卷调查程序,共有3个页面,分别是one.jsp.two.jsp.three.jsp. 其中,shiyan6_1_one.jsp页面效果如下图所示 ...

  4. 【BZOJ3771】Triple 生成函数 FFT 容斥原理

    题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...

  5. PHP 公共方法分享180628

    查看php 类的详情:方法.常量.属性( type(new \Illuminate\Http\Request());) /** * fixme 打印类详情 * @param $class object ...

  6. 【Gym 100947I】What a Mess

    BUPT 2017 summer training (for 16) #1D 题意 找到n个数里面有多少对具有倍数关系.\(1 ≤ n ≤ 10^4,2 ≤ a_i ≤ 10^6\) 题解 枚举一个数 ...

  7. 【HDU 4343】Interval query(倍增)

    BUPT2017 wintertraining(15) #8D 题意 给你x轴上的N个线段,M次查询,每次问你[l,r]区间里最多有多少个不相交的线段.(0<N, M<=100000) 限 ...

  8. bzoj4671: 异或图

    bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...

  9. Hdoj 1374.Knight Moves 题解

    Problem Description A friend of you is doing research on the Traveling Knight Problem (TKP) where yo ...

  10. [复习]动态dp

    [复习]动态dp 你还是可以认为我原来写的动态dp就是在扯蛋. [Luogu4719][模板]动态dp 首先作为一个\(dp\)题,我们显然可以每次修改之后都进行暴力\(dp\),设\(f[i][0/ ...