MooFest
Time Limit: 1000MS |
|
Memory Limit: 30000K |
Total Submissions: 6265 |
|
Accepted: 2765 |
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
Source
USACO 2004 U S Open
题目大意:一群牛参加完牛的节日后都有了不同程度的耳聋,第i头牛听见别人的讲话,别人的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。
解题思路:首先要根据音量f进行排序,这样就可以进行优化,即对于某一头牛i来说,排在他前面的音量都比他小,肯定是用i自身的音量*两者之间的距离。此时的计算公式为:(求解比当前x小的所有和)
(x-x1)*f;
(x-x2)*f;
(x-x3)*f........
综上为:(n*x(x1+x2+x3+.....))*f; 注释:x表示某一头牛当前的位置,x1,x2,x3......等表示排在他前面的牛的位置,f当前这头牛的音量,因为他是最大的音量。(这里的距离我们需要采用树状数组进行求解)
这里有个地方需要解释一下,就是排在这个牛i前面的音量一定都比他小,但是坐标值x不一定比他小,所以我们只能分开处理。
我们可以在建立一个数轴,一个点一个点的放进去,先放进去的音量肯定是小的,把他按照该有的固定位置放进去,这样排在他前面的所有x都比他小就可以按照上面的方法采用树状数组的方法进行区间求和。(这里要放入一个求解一次他左边和右边的值,左边就是比当前x小的,右边是比当前x大的)。
下面介绍比当前值x大的情况计算方法:
(x1-x)*f;
(x2-x)*f;
(x3-x)*f........
综上:((x1+x2+x3+......)-n*x)*f;
这里的n值就应该等于放进去的所有牛的个数-前面已经计算过的比他x小的个数:i-nn;
(x1+x2+x3+...)就应该等于总和减去比他小的x的和。
要用long long !!!
这样讲起来很复杂,详情请看代码实现~~~~不懂得评论
详见代码。
#include
#include
#include
#include
using namespace std;
#define ll long long
struct node
{
ll f,x;
} s[20010];
int n;
ll c1[20010],c2[20010];
ll a1[20010],a2[20010];
bool cmp(node a,node b)
{
return a.f