每年,农夫约翰的N(1 <= N <= 20,000)只牛会参加“MooFest”,一个来自世界各地的牛的社交聚会。 MooFest有许多活动,包括干草堆积,篱笆跳跃,把尾巴钉在农夫的身上...当奶牛都站在同一个地方排队,他们会大声喊叫,吼声几乎震耳欲聋。事实上,每年参加了这个活动后,一些奶牛已经失去了部分听力。
每个奶牛具有耳背值v(i)(在1..20,000的范围内)。如果一头牛向牛i吼叫,她必须使用至少是两头母牛之间距离的v(i)倍的声音,以便被牛i听到。如果两个奶牛i和j想要交谈,她们必须以等于她们之间的距离乘以max(v(i),v(j))的音量说话。
假设N头奶牛中的每头奶牛都站在直线上(每头奶牛在1..20,000范围内的某个独特x坐标),每对奶牛都使用尽可能小的声音进行谈话。
计算所有N(N-1)/ 2对正在说话的奶牛产生的所有声音的总和。
每个奶牛具有耳背值v(i)(在1..20,000的范围内)。如果一头牛向牛i吼叫,她必须使用至少是两头母牛之间距离的v(i)倍的声音,以便被牛i听到。如果两个奶牛i和j想要交谈,她们必须以等于她们之间的距离乘以max(v(i),v(j))的音量说话。
假设N头奶牛中的每头奶牛都站在直线上(每头奶牛在1..20,000范围内的某个独特x坐标),每对奶牛都使用尽可能小的声音进行谈话。
计算所有N(N-1)/ 2对正在说话的奶牛产生的所有声音的总和。
*第1行:单个整数,N
*第2到N + 1行:两个整数:牛的耳背值v和x坐标。第2行代表第一头牛;第3行表示第二头牛;等等。没有两头牛会站在同一个位置。
*第2到N + 1行:两个整数:牛的耳背值v和x坐标。第2行代表第一头牛;第3行表示第二头牛;等等。没有两头牛会站在同一个位置。
*第1行:仅含单个整数,表示所有牛互相吼叫的所有声音的总和。
4 3 1 2 5 2 6 4 3
57
思路:当两头牛进行计算时,用到的是V值大的牛。所以先按照V值从大到小排序,当计算某头牛时,只考虑V值比它小的那些牛。我们用两个树状数组分别表示牛的坐标之和及牛的数量之和(以坐标作为数组下标)。那么考虑牛i时(按V从大到小排序后),设坐标值比它小的那些牛的数目为num1、坐标之和为sum1,坐标值比它大的那些牛的数目为num2、坐标之和为sum2,那么对该牛而言(设坐标为X,体力值为V),所贡献的答案为V * ( X*num1-sum1 + sum2-X*num2 )。
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 20000 + 10;
struct Node {
int x, v;
bool operator < (const Node& rhs) const {
return v > rhs.v;
}
}p[maxn];
int C1[maxn], C2[maxn], n, mx;
int lowbit(int x) {
return x & -x;
}
int Sum(int *a, int x) {
int ans = 0;
while(x > 0) {
ans += a[x];
x -= lowbit(x);
}
return ans;
}
void add(int *a, int x, int v) {
while(x < maxn) {
a[x] += v;
x += lowbit(x);
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].v, &p[i].x);
add(C1, p[i].x, p[i].x);
add(C2, p[i].x, 1);
}
sort(p+1, p+n+1);
ll ans = 0;
for(int i = 1; i < n; i++) {
add(C1, p[i].x, -p[i].x);
add(C2, p[i].x, -1);
int sum1 = Sum(C1, p[i].x);
int num1 = Sum(C2, p[i].x);
int sum2 = Sum(C1, mx) - sum1;
int num2 = Sum(C2, mx) - num1;
ans += (ll)(p[i].x * num1 - sum1 + sum2 - p[i].x * num2) * (ll)(p[i].v);
}
printf("%lld\n", ans);
return 0;
}
博客介绍了如何利用树状数组解决POJ 1990题目的思路。首先按照牛的体力值从大到小排序,然后通过两个树状数组分别记录坐标之和和牛的数量之和。对于每头牛,计算其对答案的贡献,即体力值乘以特定坐标差值。
&spm=1001.2101.3001.5002&articleId=62238214&d=1&t=3&u=7d8816245d224049bf4cfb2bffad4496)
899

被折叠的 条评论
为什么被折叠?



