# POJ 1990 MooFest(想法题&树状数组)

154 篇文章 0 订阅
119 篇文章 0 订阅
111 篇文章 1 订阅

MooFest
Time Limit:  1000MS
Memory Limit:  30000K

Description

Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves a variety of events including haybale stacking, fence jumping, pin the tail on the farmer, and of course, mooing. When the cows all stand in line for a particular event, they moo so loudly that the roar is practically deafening. After participating in this event year after year, some of the cows have in fact lost a bit of their hearing.

Each cow i has an associated "hearing" threshold v(i) (in the range 1..20,000). If a cow moos to cow i, she must use a volume of at least v(i) times the distance between the two cows in order to be heard by cow i. If two cows i and j wish to converse, they must speak at a volume level equal to the distance between them times max(v(i),v(j)).

Suppose each of the N cows is standing in a straight line (each cow at some unique x coordinate in the range 1..20,000), and every pair of cows is carrying on a conversation using the smallest possible volume.

Compute the sum of all the volumes produced by all N(N-1)/2 pairs of mooing cows.

Input

* Line 1: A single integer, N

* Lines 2..N+1: Two integers: the volume threshold and x coordinate for a cow. Line 2 represents the first cow; line 3 represents the second cow; and so on. No two cows will stand at the same location.

Output

* Line 1: A single line with a single integer that is the sum of all the volumes of the conversing cows.

Sample Input

4
3 1
2 5
2 6
4 3


Sample Output

57

1. 首先将这n个点按照v值从小到大排序（后面说的排在谁的前面，都是基于这个排序）。

2. 用两个树状数组，一个记录比xi小的点的个数a，一个记录比xi小的点的位置之和b，

/*47ms,800KB*/

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 20001
using namespace std;

long long num[2][MAXN];

struct Node
{
long long v, x;
bool operator < (const Node& a) const
{
return v < a.v;//按音量排序
}
} node[MAXN];

long long sum(int pos, int d)
{
long long ans = 0;
while (pos > 0)
{
ans += num[d][pos];
pos -= -pos & pos;
}
return ans;
}

void update(int pos, long long v, int d)
{
while (pos < MAXN)
{
num[d][pos] += v;
pos += -pos & pos;
}
}

int main()
{
int n;
scanf("%d", &n);
memset(num, 0, sizeof(num));
for (int i = 1; i <= n; i++)
scanf("%lld%lld", &node[i].v, &node[i].x);
sort(node + 1, node + 1 + n);

long long a, b, ans = 0;
for (int i = 1; i < n;)
{
update(node[i].x, 1, 0);//有点，就+1
update(node[i].x, node[i].x, 1);//把位置xi放到树状数组b中
a = sum(node[++i].x, 0);
b = sum(node[i].x, 1);
//稍微化简了下
ans += (sum(MAXN - 1, 1) - (b << 1) - (i - 1 - (a << 1)) * node[i].x) * node[i].v;
}
printf("%lld\n", ans);
return 0;
}


• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
08-06 293
03-29 251
03-17 367
03-27 159
04-14
04-14
11-29 286
08-24 175
01-31 154
08-11 401
11-19 344
10-15 1188

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。