MooFest POJ - 1990 (樹狀陣列)
阿新 • • 發佈:2018-11-06
題意:給出牛的耳聾程度和牛所在的位置,之後求出每兩個牛所能聽到對方的聲音的和,每兩個牛的計算公式為max(vi,vj)*|xi-xj|
題解:首先暴力肯定是不行的,那麼可以按照牛的音量進行從小到大排序,然後維護兩個樹狀陣列,一個維護此位置之前之後的牛的個數,另一個維護此位置之前之後的牛的位置之和,之後求和即可.
附上程式碼:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2e4+50; pair<int,int>cow[maxn]; int n; ll cnt[maxn],dis[maxn]; int lowbit(int i) { return i&(-i); } ll sum(ll *bit,int i) { ll res=0; while(i>0){ res+=bit[i]; i-=lowbit(i); } return res; } ll sum(ll *bit,int from,int to) { return sum(bit,to)-sum(bit,from); } void add(ll *bit,int i,ll x) { while(i<=maxn){ bit[i]+=x; i+=lowbit(i); } } int main() { scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d%d",&cow[i].first,&cow[i].second); } sort(cow,cow+n); ll ans=0; for(int i=0;i<n;i++){ int v=cow[i].first,x=cow[i].second; int lcnt=sum(cnt,0,x),rcnt=sum(cnt,x,maxn); ans+=v*((x*lcnt-sum(dis,0,x))+(sum(dis,x,maxn)-rcnt*x)); add(cnt,x,1); add(dis,x,x); } printf("%lld\n",ans); return 0; }