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.Input
* Line 1: A single integer, NOutput
* 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