链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
本题为hard版本,和easy版本的唯一区别是ai有可能为负数!
小红拿到了一个数组,她想知道,有多少非空区间满足区间所有元素之和不小于k?
输入描述:
第一行输入两个正整数n,k,用空格隔开。 第二行输入n个整数ai,代表数组的元素。 1 <= n <= 1e5 -1e9 <= ai <= 1e9 1 <= k <= 1e14
输出描述:
输出一个整数表示满足条件区间的数量。
示例1
输入
5 5 1 4 2 1 3
输出
8
示例2
输入
4 5 2 -100 5 6
输出
3
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t[200005]; //树状数组
void add(int x,int v){
for(int i = x;i <= 2e5 + 5;i += (i & -i)){
t[i] += v;
}
}
int ask(int x){
int res = 0;
for(int i = x;i >= 1;i -= (i & -i)){
res += t[i];
}
return res;
}
signed main(){
int n,k;
cin >> n >> k;
map<int,int> mp;
vector<int> pre(n + 1);
for(int i = 1;i <= n;i ++){
int a;
cin >> a;
pre[i] = pre[i - 1] + a;
mp[pre[i]] = 1;
mp[pre[i] - k] = 1;
}
mp[0] = 1; //注意此步不可少
int cnt = 1;
for(auto &it:mp){ //离散化
it.second = cnt ++;
}
add(mp[0],1); //注意此步不可少
int ans = 0;
for(int i = 1;i <= n;i ++){
ans += ask(mp[pre[i] - k]);
add(mp[pre[i]],1);
}
cout << ans << "\n";
return 0;
}
ps:此题写了好几遍再次见到还是没思路,所以整理下。