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.
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 <br> <br>* 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. <br>
Output
* Line 1: A single line with a single integer that is the sum of all the volumes of the conversing cows. <br>
Sample Input
4 3 1 2 5 2 6 4 3
Sample Output
57
挺不错的一道题目,题意是给出n个互不相同的点xi,每个点有一个对应的值vi,求每对点(i,j)间的abs(xi-xj)*max(vi,vj)之和,
首先,解决怎么找vi大的可以将所有点按vi排序,这样的话,我们从前往后循环,循环到的当前的数就是目前vi最大的
其次,如果是两两点间距离求绝对值相加的话太慢,那怎么求距离,这里用到树状数组,看来这是树状数组比较经典的一种用法,就是用两个树状数组tree0,tree1,sum(tree0)存放坐标比当前坐标小的点的个数,sum(tree1)存放比当前坐标小的距离的总和,可以直接求一个点与其他点距离的总和,又把距离和拆成坐标比a[i].x大的点到a[i].x距离之和与比a[i].x小的点到a[i].x距离之和
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
#define M 20005
struct node { //存放点信息,按v升序排列
int v,x;
bool operator < (const node & obj)const
{
return v<obj.v;
}
}a[M];
int n;
int tree[2][M];
inline int lowbit(int i) {return i&(-i);}
void add(int t,int i,int v)
{
while(i<=M)
{
tree[t][i]+=v;
i+=lowbit(i);
}
}
ll sum(int t,int i)
{
ll res=0;
while(i>0)
{
res+=tree[t][i];
i-=lowbit(i);
}
return res;
}
int main()
{
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i].v,&a[i].x);
}
sort(a+1,a+n+1);
ll sum0,sum1,t1,t2,ans=0,tot=0; //ans是结果,tot是到当前元素的已经出现过的元素的坐标之和
for(i=1;i<=n;i++) //i是当前处理的点,为避免两点间重复计算,所以只计算i与之前出现过的点的结果,
{ //当前的点i是目前v最大的,但是前面元素的坐标可能分布在i的坐标的两侧
tot+=a[i].x;
add(0,a[i].x,1); //维护树状数组tree0
add(1,a[i].x,a[i].x); //维护tree1
sum0=sum(0,a[i].x); //sum0代表在已经出现的点中坐标比a[i].x小的个数
sum1=sum(1,a[i].x); //sum0代表在已经出现的点中坐标比a[i].x小的坐标之和
t1=sum0*a[i].x-sum1; //坐标比a[i].x小的点到a[i].x距离之和
t2=tot-sum1-a[i].x*(i-sum0); //坐标比a[i].x大的点到a[i].x距离之和
ans+=(t1+t2)*a[i].v;
}
printf("%I64d\n",ans);
return 0;
}