您的位置:首页 > 其它

ZJNU 1712 树状数组

2017-02-27 17:34 369 查看
VUDU

Time Limit: 5000MS Memory Limit: 5000K

Total Submissions: 63 Accepted: 23

Description

Young Mirko has been buying voodoo dolls lately. Considering that he is very interested in the cheapest purchase possible, he has been tracking the prices of voodoo dolls each day. His price list consists of doll prices in the last N days, where doll price ai represents the price of a doll i days ago. Mirko thinks he has noticed a connection between the average doll price in a sequence of consecutive days and the price on the following day. He wants to test his hunch and is puzzled by a very interesting question: “For a given P, how many different consecutive subsequences in the last N days are there, when the average doll price was greater than or equal to P?” Two consecutive subsequences are considered different if their beginnings or ends are different.

Input

The first line of input contains the integer N, the sequence length (1 <= N <= 1 000 000). The second line of input contains N prices ai (0 <= ai <= 1 000 000 000). The third line of input contains an integer P. (0 <= P <= 1 000 000 000).

Output

The first and only line of output must contain the answer to Mirko’s question for a given P.

Sample Input

3

1 2 3

3

Sample Output

1

Sample Input

3

1 3 2

2

Sample Output

5

Sample Input

3

1 3 2

3

Sample Output

1

题目链接

题意:给你一个有n个数的集合,让你求有多少个连续的子集,他所有数的平均值大于等于k

解题思路:我们可以先将集合中的每个数都减去k,然后求前缀和,这样,对于第n项,我们只需知道1到n-1项的前缀和有多少个是小于等于它的就可以了。然而如果暴力的话时间复杂度为O(n^2),所以我们可以用树状数组解决这个问题。因为数据过大,所以不能用前缀和作为数组元素,因此还要求用sort和编号进行操作。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
long long sum;
int bh;
}e[1000001];
long long ans[1000001];
int n;
bool cmp(const node &a,const node &b)
{
if(a.sum!=b.sum)return a.sum<b.sum;
return a.bh<b.bh;
}
void update(int x)
{
while(x<=n+1)
{
ans[x]++;
x+=(x&-x);
}
}
int Sum(int x)
{
long long ret=0;
while(x>0)
{
ret+=ans[x];
x-=(x&-x);
}
return ret;
}
int main()
{
int p;
scanf("%d",&n);
long long sum=0;
for(int i=1;i<=n;i++)
{
long long s;
scanf("%lld",&s);
e[i].sum=s;
e[i].bh=i+1;
}
scanf("%d",&p);
e[n+1].sum=0;
e[n+1].bh=1;
for(int i=1;i<=n;i++)
{
e[i].sum+=e[i-1].sum-p;
}
sort(e+1,e+2+n,cmp);
long long pri=0;
for(int i=1;i<=n+1;i++)
{
pri+=Sum(e[i].bh);
update(e[i].bh);
}
printf("%lld\n",pri);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ZJNU-1712 树状数组