poj 1990 MooFest (树状数组)
2013-09-19 13:24
417 查看
题目:http://poj.org/problem?id=1990
思路见代码:
思路见代码:
#include<cstdio> #include<algorithm> #include<cstdlib> #include<iostream> using namespace std; const int MAX_N=20000+5; typedef long long ll; /*cnt:= 坐标小于 x的点的个数(cnt[x]) cntsum:= 坐标小于x的坐标点总和 */ ll cnt[MAX_N],cntsum[MAX_N]; int N; struct cow{ ll v,x; }nc[MAX_N]; bool cmp(cow a,cow b){ return a.v<b.v; } void update(ll *cnt,int x,int w) { while(x<=MAX_N) { cnt[x] += w; x += x&(-x); } } ll sum(ll *cntsum,int x) { ll res=0; while(x) { res += cntsum[x]; x -= x&(-x); } return res; } int main() { while(cin>>N) { for(int i=0;i<N;i++){ cin>>nc[i].v>>nc[i].x; } sort(nc,nc+N,cmp); ll tot=0,res=0; for(int i=0;i<N;i++) { ll num1=sum(cnt,nc[i].x); ll num2=sum(cntsum,nc[i].x); /* 考虑统计第i头牛,之前统计的i-1头牛v都小于等于v[i], 这些牛的坐标小于x[i]的头数为cnt[i], 这些小于x[i]的总坐标和为cntsum[i] 那这第i头牛和之前的牛交流的总和分为两部分,一部分是坐标在x之前的, 一部分是坐标在x之后的。 (cnt[i]*x[i]-cntsum[i])*v[i]为坐标在x[i]之前的牛的总和 tot为之前i-1头牛的总的坐标和,那么tot-cntsum[i]就是 坐标在x[i]之后的所有牛的坐标和,i-num1为坐标在x[i]之后的牛的头数. */ res += nc[i].v*(num1*nc[i].x-num2+ tot-num2-(i-num1)*nc[i].x); tot += nc[i].x; update(cnt,nc[i].x,1); update(cntsum,nc[i].x,nc[i].x); } cout<<res<<endl; } return 0; }
相关文章推荐
- poj 1990 MooFest(转化成树状数组求和)
- [树状数组] poj 1990 MooFest
- 树状数组 poj 1990 MooFest
- POJ 1990 MooFest(树状数组)
- POJ 1990 MooFest(树状数组)
- poj 1990 MooFest(树状数组)
- poj-1990-MooFest(树状数组)
- POJ 1990 MooFest (树状数组)
- poj1990 MooFest && hdu3015 Disharmony Trees (树状数组)
- POJ 1990-MooFest(树状数组)
- 【poj 1990】MooFest(树状数组)
- POJ 1990 MooFest(树状数组)
- POJ 1990 MooFest【 树状数组 】
- POJ1990 MooFest——树状数组——Pku1990
- POJ 1990 MooFest(树状数组)
- poj 1990 MooFest(树状数组)
- POJ 1990 MooFest 树状数组
- poj 1990 MooFest(树状数组)
- POJ 1990 MooFest (树状数组)
- poj 1990 MooFest (树状数组)