POJ

tech2022-08-10  139

MooFest

Time Limit: 1000MS Memory Limit: 30000K

Problem 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

题意

n只奶牛,分布在一条直线上。每只奶牛有一个权值 v i v_i vi和代表位置的 x i x_i xi(每个 x i x_i xi不同)。两只奶牛 i i i j j j相互通信的代价为 m a x ( v i , v j ) ∗ ∣ x i − x j ∣ max(v_i,v_j)*|x_i-x_j| max(vi,vj)xixj。求 n ∗ ( n − 1 ) 2 \frac{n*(n-1)}{2} 2n(n1)对奶牛相互通信的代价和。

题解:

将奶牛以 v v v为主键排序。 依次“放入”奶牛,并计算它与“已放入”的奶牛通信的代价。 m a x ( v i , v j ) max(v_i,v_j) max(vi,vj)为当前奶牛的 v v v。则计算当前奶牛到其余奶牛的举例和即可。设当前奶牛左边有num1只奶牛,其坐标和为sum1,右边有num2只奶牛,坐标和为sum2。则: a n s + = v i ∗ ( n u m 1 ∗ x i − s u m 1 + s u m 2 − n u m 2 ∗ x i ) ans += v_i*(num1*x_i-sum1+sum2-num2*x_i) ans+=vi(num1xisum1+sum2num2xi)。 利用树状数组快速计算 n u m , s u m num,sum numsum即可。

#include<stdio.h> #include<iostream> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> #include<map> #include<vector> #include<queue> #include<bitset> #define dbg(x) cout<<#x<<" = "<<x<<endl; #define INF 0x3f3f3f3f #define LLINF 0x3f3f3f3f3f3f3f3f #define eps 1e-8 using namespace std; typedef long long LL; typedef pair<int, int> P; const int maxn = 20010; const int mod = 1000000007; struct node{ int v, x; bool operator<(node b)const{ return v < b.v; } }p[maxn]; int a[maxn], b[maxn], c[maxn]; int query(int x, int a[]); void Update(int x, int y, int n, int a[]); int main() { int n, m, i, j, k; LL ans = 0; scanf("%d", &n); for(i=0;i<n;i++) scanf("%d %d", &p[i].v, &p[i].x); sort(p, p+n); for(i=0;i<n;i++){ int num1 = query(p[i].x-1, c); int num2 = query(20000, c)-query(p[i].x, c); int sum1 = query(p[i].x-1, a); int sum2 = query(20000, a)-query(p[i].x, a); ans += (sum2-num2*p[i].x+num1*p[i].x-sum1)*1LL*p[i].v; Update(p[i].x, 1, 20000, c); Update(p[i].x, p[i].x, 20000, a); } printf("%lld\n", ans); return 0; } int lowbit(int x) { return x&(-x); } void Update(int x, int y, int n, int a[]) { for(int i=x;i<=n;i+=lowbit(i)) a[i] += y; } int query(int x, int a[]) { int sum = 0; for(int i=x;i>0;i-=lowbit(i)) sum += a[i]; return sum; }
最新回复(0)