poj 1990 MooFest(转化成树状数组求和)
生活随笔
收集整理的這篇文章主要介紹了
poj 1990 MooFest(转化成树状数组求和)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:一群牛參加完牛的節日后都有了不同程度的耳聾,第i頭牛聽見別人的講話,別人的音量必須大于v[i],當兩頭牛i,j交流的時候,交流的最小聲音為max{v[i],v[j]}*他們之間的距離?,F在有n頭牛,求他們之間兩兩交流最少要的音量和。
解題思路:先將v按從小到大排序,這樣對于vi,那么vi之前的牛所交流的聲音就是vi,vi很好確定,但關鍵就是怎么算距離了。我們可以用兩個樹狀數組,一個維護vi之前有多少頭牛距離比i小,另一個就是維護vi之前距離比i小的總距離。
那么就可以推出一個關系式:對于第i頭牛,它對答案所做的貢獻為(small * x - Xmin + Xmax - big * x)* vi ,其中small是比i距離小的個數,big是比i距離大的個數,Xmin是比i距離小的所有牛的總距離和,Xmax是比i距離大的所有牛的總距離和。
這道題自己推出來感覺好爽。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;typedef __int64 LL; const int maxn = 20005; struct Node {int x,v; }cow[maxn]; struct Tree {int n;LL c[maxn];void init(int n){this->n = n;memset(c,0,sizeof(c));}int lowbit(int x){return x & -x;}void update(int x,int d){while(x <= n){c[x] += d;x += lowbit(x);}}LL sum(int x){LL ans = 0;while(x > 0){ans += c[x];x -= lowbit(x);}return ans;} }cnt,val; int n,idx[maxn]; bool cmp1(Node a,Node b) {return a.v < b.v; }bool cmp2(Node a,Node b) {return a.x < b.x; }void discrete() {int tot = 0;sort(cow+1,cow+1+n,cmp2);tot = 0;for(int i = 1; i <= n; i++){if(cow[i].x != cow[i-1].x)idx[cow[i].x] = ++tot;}sort(cow+1,cow+1+n,cmp1); }int main() {while(scanf("%d",&n)!=EOF){for(int i = 1; i <= n; i++)scanf("%d%d",&cow[i].v,&cow[i].x);discrete();cnt.init(n);val.init(n);LL ans = 0;for(int i = 1; i <= n; i++){ans += (cnt.sum(idx[cow[i].x]) * cow[i].x - val.sum(idx[cow[i].x])) * cow[i].v;ans += (val.sum(n) - val.sum(idx[cow[i].x]) - (cnt.sum(n) - cnt.sum(idx[cow[i].x])) * cow[i].x) * cow[i].v;cnt.update(idx[cow[i].x],1);val.update(idx[cow[i].x],cow[i].x);}printf("%I64d\n",ans);}return 0; }
總結
以上是生活随笔為你收集整理的poj 1990 MooFest(转化成树状数组求和)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows环境配置Apache+My
- 下一篇: 使用TortoiseGit提交代码到Gi