日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

poj 1990 MooFest(转化成树状数组求和)

發布時間:2025/3/16 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj 1990 MooFest(转化成树状数组求和) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意:一群牛參加完牛的節日后都有了不同程度的耳聾,第i頭牛聽見別人的講話,別人的音量必須大于v[i],當兩頭牛i,j交流的時候,交流的最小聲音為max{v[i],v[j]}*他們之間的距離。現在有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(转化成树状数组求和)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。