POJ 1990 MooFest(二維樹狀陣列)

2021-07-04 21:36:34 字數 1149 閱讀 4529

解題思路:

題目大意:

farmer john有n頭牛,排列成一條直線(不會在同乙個點),給出每頭牛在直線上的座標x。另外,每頭牛還有乙個自己的聲調v,如果兩頭牛(i和j)之間想要溝通的話,它們必須用同個音

調max(v[i],v[j]),溝通起來消耗的能量為:max(v[i],v[j]) * 它們之間的距離.

問要使所有的牛之間都能溝通(兩兩之間),總共需要消耗多少能量.

演算法思想:

因為要求max(vi,vj),所以先讀入所有的牛,將牛按它的vi值從小到大排序,所以當前處理的牛總是vi值最大的。

接下來就要算當前第i頭牛的座標xi和之前出現的所有牛的座標之差的總和了。維護兩個樹狀陣列,陣列1的sum(1,x)表示的

是座標值<=x的牛出現了多少條,陣列2的

sum(2,x)表示座標值<=x的牛的座標值總和是多少。

那麼假設當前處理第i頭牛,維護當前已經處理了的所有牛的座標和total,並執行:add(1,x[i],1),add(2,x[i],x[i])

那麼對於牛i來說:

它左邊所有牛和它的座標差值和為:

tmp1 =sum(1,x[i])*x[i]-sum(2,x[i]).

右邊的座標差值和為:

tmp2=total-sum(2,x[i])-x[i]*(i-sum(1,x[i])).

所以最終結果:ans +=(temp1+temp2)*v[i]。

結果可能超出int要用long long。

ac**:

#include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 20000;

struct node

}node[maxn+10];

int c[3][maxn+10];

int lowbit(int x)

void update(int i,int x,int v)

}int sum(int i,int x)

return res;

}int main()

printf("%lld\n",ans);

}return 0;

}

POJ 1990 MooFest 樹狀陣列

思路 定義兩棵樹狀陣列,第乙個記錄座標個數和,第二個記錄橫座標和。對volumn從小到大排序,保證遍歷更新的時候當前的volumn取最大。lescnt表示前i 1個比第i個橫座標小的cow的總數。lessum表示前i 1個橫座標比當前小的橫座標之和 bigcnt表示前i 1個比當前橫座標大的cow的...

poj 1990 MooFest 樹狀陣列

題意就是有n頭牛,每頭牛都有乙個座標和聲調值 x,v 兩頭牛之間通訊要花費的能量是他們的距離乘以最大的乙個音調值,現在要任意兩頭牛之間都相互通訊一次,求總共需要花費多少能量?顯然總共有n n 1 2條,我們可以用樹狀陣列儲存,樹狀陣列很適合求區間的和,我們只需要求出某頭牛左右兩邊分別有多少頭牛比它的...

POJ 1990 MooFest 樹狀陣列

題意 就算每兩頭牛之間聲音值 2頭牛v的最大值 2頭牛之間的距離 思路 按照v從小到大插入樹狀陣列 因為從小到大排序 每插入一頭牛i 當前v最大值就是牛i的v 統計x比他小的個數s1 x比他大的個數s2 s2 就是當前樹狀陣列牛的數量減去s1在減一 統計x比他小的距離l1 和 x比他大的距離l2 l...