AtCoder Regular Contest 075 E - Meaningful Mean(树状数组)
E - Meaningful Mean
Time limit : 2sec / Memory limit : 256MB
Score : 600 points
Problem Statement
You are given an integer sequence of length N, a= {a1,a2,…,aN}, and an integer K.
a has N(N+1)⁄2 non-empty contiguous subsequences, {al,al+1,…,ar} (1≤l≤r≤N). Among them, how many have an arithmetic mean that is greater than or equal to K?
Constraints
All input values are integers.
1≤N≤2×105
1≤K≤109
1≤ai≤109
Input
Input is given from Standard Input in the following format:
N K
a1
a2
:
aN
Output
Print the number of the non-empty contiguous subsequences with an arithmetic mean that is greater than or equal to K.
Sample Input 1
Copy
3 6
7
5
7
Sample Output 1
Copy
5
All the non-empty contiguous subsequences of a are listed below:
{a1} = {7}
{a1,a2} = {7,5}
{a1,a2,a3} = {7,5,7}
{a2} = {5}
{a2,a3} = {5,7}
{a3} = {7}
Their means are 7, 6, 19⁄3, 5, 6 and 7, respectively, and five among them are 6 or greater. Note that {a1} and {a3} are indistinguishable by the values of their elements, but we count them individually.
Sample Input 2
Copy
1 2
1
Sample Output 2
Copy
0
Sample Input 3
Copy
7 26
10
20
30
40
30
20
10
Sample Output 3
Copy
13
题意:给出 \(N(1 \leq N \leq 2 \times 10^5)\) 个数和 \(K\) ,\(1 \leq a[i] \leq 10^9\),求多少个连续区间使得他们的平均值大于等于 \(K\).
题解:
每个数减去 \(K\),然后求前缀和 \(sum[i]\),那么就是对每个 \(i\) 求有多少个 \(j\) 使得 \(sum[j-1]<=sum[i]\),将 \(sum\) 数组进行离散化,用 "权值树状数组" 即可。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=2e5+100;
ll sum[maxn];
int c[maxn];
int cnt=0;
void add(int x)
{
while(x<=cnt)
{
c[x]++;
x+=x&(-x);
}
}
int get_sum(int x)
{
int ans=0;
while(x)
{
ans+=c[x];
x-=x&(-x);
}
return ans;
}
ll h[maxn];
int v[maxn];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
rep(i,1,n+1) scanf("%lld",&sum[i]),sum[i]-=1ll*k;
rep(i,1,n+1) sum[i]=sum[i-1]+sum[i],h[i]=sum[i];
sort(h+1,h+n+1);
cnt=unique(h+1,h+n+1)-h-1;
ll ans=0;
rep(i,1,n+1)
{
int pos=lower_bound(h+1,h+cnt+1,sum[i])-h;
if(sum[i]>=0) ans++; //此时是[1,i]全选
ans+=get_sum(pos);
add(pos);
}
printf("%lld\n",ans);
return 0;
}