D. Petya and Array 树状数组

题意:

给出一个数组,元素有正有负有0,问其区间和小于 t 的子区间的个数。

sum[ r ]-sum[ l-1 ]<t,其中sum是a的前缀和。

实现的方法就是从前往后对于每一个sum[ i ],看在它前面有多少个大于等于sum[ i ] - t 的前缀和。

树状数组维护的是 i 前面有几个数小于等于它

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <iostream>
 8 #include <map>
 9 #include <stack>
10 #include <string>
11 #include <vector>
12 #include <bits/stdc++.h>
13 #define  pi acos(-1.0)
14 #define  eps 1e-9
15 #define  fi first
16 #define  se second
17 #define  rtl   rt<<1
18 #define  rtr   rt<<1|1
19 #define  bug         printf("******\n")
20 #define  mem(a,b)    memset(a,b,sizeof(a))
21 #define  name2str(x) #x
22 #define  fuck(x)     cout<<#x" = "<<x<<endl
23 #define  f(a)        a*a
24 #define  sf(n)       scanf("%d", &n)
25 #define  sff(a,b)    scanf("%d %d", &a, &b)
26 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
27 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
28 #define  pf          printf
29 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
30 #define  FREE(i,a,b) for(i = a; i >= b; i--)
31 #define  FRL(i,a,b)  for(i = a; i < b; i++)+
32 #define  FRLL(i,a,b) for(i = a; i > b; i--)
33 #define  FIN         freopen("data.txt","r",stdin)
34 #define  gcd(a,b)    __gcd(a,b)
35 #define  lowbit(x)   x&-x
36 #define rep(i,a,b) for(int i=a;i<b;++i)
37 #define per(i,a,b) for(int i=a-1;i>=b;--i)
38 using namespace std;
39 typedef long long  LL;
40 typedef unsigned long long ULL;
41 const int INF = 0x3f3f3f3f;
42 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
43 const int maxn = 2e5 + 7;
44 int n;
45 LL a[maxn], sum[maxn], t, cnt[maxn], c[maxn];
46 void update ( int pos, LL x ) {
47     while ( pos <= n + 1 ) {
48         c[pos] += x;
49         pos += lowbit ( pos );
50     }
51 }
52 LL getsum ( int pos ) {
53     LL sum = 0;
54     while ( pos > 0 ) {
55         sum += c[pos];
56         pos -= lowbit ( pos );
57     }
58     return sum;
59 }
60 int main() {
61     scanf ( "%d%lld", &n, &t );
62     for ( int i = 1 ; i <= n ; i++ ) {
63         scanf ( "%lld", &a[i] );
64         sum[i] = sum[i - 1] + a[i];
65         cnt[i] = sum[i];
66     }
67     sort ( cnt, cnt + n + 1 );
68     LL ans = 0;
69     for ( int i = 1 ; i <= n ; i++ ) {
70         int  pos = lower_bound ( cnt, cnt + n + 1, sum[i - 1] ) - cnt + 1;//树状数组下标不能是0 所以需要将下标++
71         update ( pos, 1 );
72         pos = lower_bound ( cnt, cnt + n + 1, sum[i] - t + 1 ) - cnt; //求有多少个数小于等于sum[i] - t
73         ans += ( i - getsum ( pos ) );//区间的总数是 i-1 小于等于的个数是  getsum ( pos ) - 1
74     }
75     printf ( "%lld\n", ans );
76     return 0 ;
77 }

原文地址:https://www.cnblogs.com/qldabiaoge/p/10539357.html

时间: 2024-10-03 12:54:11

D. Petya and Array 树状数组的相关文章

HDU 3854 Glorious Array(树状数组)

题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于K的结点有多少对,K是一个定值. 思路:先求最初时候小于k的结点有多少对,然后每次改变颜色的时候,统计该点左侧和右侧各有多少同色和异色的结点(这一步使用树状数组),分别处理就行.另外需要预处理离某个结点最近的两个距离小于K的结点的位置. 代码写的略乱. #include<cstdio> #

HDU-4947-GCD Array(树状数组+莫比乌斯反演)

Problem Description Teacher Mai finds that many problems about arithmetic function can be reduced to the following problem: Maintain an array a with index from 1 to l. There are two kinds of operations: 1. Add v to ax for every x that gcd(x,n)=d. 2.

1042.D Petya and Array 前缀 + 树状数组

11.19.2018 1042.D Petya and ArrayNew Point: 前缀 + 树状数组 :树状数组逐个维护前缀个数 Describe: 给你一个数组,一个标记数,问你有多少区间[l,r]使得这个区间的和小于这个标记数值 Solution: 没能想到 前缀数组 + 树状数组快速查询 记录前缀数组sum[i],得到区间和为sum[i] - sum[j] < t,转化为求sum[i] - t < sum[j],遍历i,求取情况,然后利用树状数组快速查询符合的区间j的个数 树状数组

Codeforces 220B - Little Elephant and Array 离线树状数组

This problem can be solve in simpler O(NsqrtN) solution, but I will describe O(NlogN) one. We will solve this problem in offline. For each x (0?≤?x?<?n) we should keep all the queries that end in x. Iterate that x from 0 to n?-?1. Also we need to kee

树状数组模板 Tree Array

---恢复内容开始--- 这几天去浙江省选当垫底(Orz我是蒟蒻),然后顺便复习下树状数组 关于树状数组,其实很好理解,主要就是lowbit()操作的巧妙 树状数组是一种非常优雅的数据结构.当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一区间元素之和的时候,可以考虑使用树状数组. 换句话说,树状数组最基本的应用: 对于一个数组,如果有多次操作,每次的操作有两种:1.修改数组中某一元素的值,2.求和,求数组元素a[1]+a[2]+…a[num]的和. ——Km的小天地 其实树状数组自己写

51nod_1199 树的先跟遍历+区间更新树状数组

题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359185.html 放代码如下: 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeL

HDU 5775:Bubble Sort(树状数组)

http://acm.hdu.edu.cn/showproblem.php?pid=5775 Bubble Sort Problem Description P is a permutation of the integers from 1 to N(index starting from 1).Here is the code of Bubble Sort in C++. for(int i=1;i<=N;++i) for(int j=N,t;j>i;—j) if(P[j-1] > P

Thair数 树状数组

题目: Erwin最近对一种叫"thair"的东西巨感兴趣... 在含有n个整数的序列a1,a2......an中, 三个数被称作"thair"当且仅当i<j<k且ai<aj<ak 求一个序列中"thair"的个数. Input (thair.in) 开始一个正整数n, 以后n个数a1~an. Output (thair.out) "thair"的个数 Sample Input Output 4 2 1

【BZOJ1103】大都市meg(DFS序,树状数组)

题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 思路:本题的特殊性质: 1.一次只标记一条边且没有重边 2.直接求1到x的路径,不用LCA 记录i点在DFS序中第一次与最后一次出现的时间b[i]与c[i] 可以发现若(x,y)(x<y)边被标记只对区间(b[y],c[y])有1的贡献 等价于前缀和s[b[y]]++ s[c[y]+1]-- 至于s[c