求区间均值大于K区间数---树状数组
来源:互联网 发布:seo网络推广职业规划 编辑:程序博客网 时间:2024/06/05 17:27
http://arc075.contest.atcoder.jp/tasks/arc075_c
题意:
给你一个序列和一个数k,求有多少对l,r,使得a[l]+a[l+1]+...+a[r]的算术平均数大于等于k
- 1≤N≤2×10^5
- 1≤K≤10^9
- 1≤ai≤10^9
思路:
首先对于所有数减去k,这样就不用除(r-l+1), 然后我们发现所求的就是有多少对l,r,使得sum[r]-sum[l-1] >= 0, sum是减去k之后的序列的前缀和
用树状数组对sum求有多少个顺序对,多加一个0这个数,代表从sum[r]-sum[0]对答案的贡献。
由于sum[i]可能很大,所以需要离散化。
#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn = 2e5+10;ll n,k,x,s[maxn],tree[maxn];vector<ll> v;void add(ll x){ while(x < maxn){ tree[x] += 1; x += x&-x; }}ll sum(ll x){ ll res = 0; while(x > 0){ res += tree[x]; x -= x&-x; } return res;}int main(){ freopen("a.txt","r",stdin); scanf("%d%d",&n,&k) ; for(int i=1; i<=n; i++){ x = read(); x -= k; s[i] = s[i-1]+x; } //把s[0]=0加进前缀和一起排序 for(int i=0; i<=n; i++) v.push_back(s[i]); sort(v.begin(),v.end()); v.resize(unique(v.begin(),v.end())-v.begin());//去重 //离散化 for(int i=0; i<=n; i++) s[i] = lower_bound(v.begin(),v.end(),s[i])-v.begin()+1; ll ans = 0; //s数组已经包含了0在内的排序序号//先统计个数,现更新 for(int i=0; i<=n; i++){ ans += sum(s[i]); printf("before update %d ans:%d ",s[i],ans);for(int j=0;j<=n;j++) printf("%d ",tree[j]);printf("\n"); add(s[i]); } cout << ans << endl; return 0;}
阅读全文
0 0
- 求区间均值大于K区间数---树状数组
- 树状数组求区间最大值
- 树状数组求区间和
- 树状数组求区间极值
- 树状数组求区间极值
- 树状数组求区间和
- 树状数组求区间最大值
- HDU 4777 树状数组求区间内 与该区间都互质的数个数
- hdu4777 Rabbit Kingdom 离线树状数组 求询问区间内的区间数
- 树状数组求区间最值(转载)
- 树状数组求区间最值
- 树状数组求区间最大值一类问题
- 树状数组--改区间求点
- 用树状数组求区间最值
- 树状数组求区间最值
- 树状数组求序列的区间和
- HDU 2852 (树状数组求第 k个 大于a 的数)
- hdu4417 树状数组(求指定区间比指定数小的数的个数)
- vue调试工具vue devtools
- 学习Java集合、布局
- [UE4]如何替换角色Mesh上的Material材质
- SSL 与 数字证书 的基本概念和工作原理
- Linux关机命令
- 求区间均值大于K区间数---树状数组
- 《统计学习方法》2——决策树
- python学习十二(自己制作模块并安装到系统、静态方法)
- 表示学习2-Deep Walk
- post 405 method not allowed
- Android5.1更改网络优先级
- 线程转储分析
- 工作日常记录 2017-09-20
- Hadoop和Spark的4大差异