POJ1990 MooFest

题解:

将耳背程度排序,那么对于每次新增一头牛时,只需要算出有前面有多少头牛的距离x比它小以及总和,还有多少头牛的距离x比它大以及总和,就可以计算了。

用2个树状数组维护

一个维护和,一个维护数目

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define LL long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=20010;
const int mod=1e9+7;
const int INF=1e9;

pair<LL,LL> p[maxn];
int n;
LL a,b;
LL Sum[maxn];
LL e[maxn],d[maxn];

int lowbit(int x){return x&-x;}

void add(int x,LL v,LL* c){
    while(x){
        c[x]+=v;
        x-=lowbit(x);
    }
}

LL sum(int x,LL* c){
    LL cnt=0;
    while(x<maxn){
        cnt+=c[x];
        x+=lowbit(x);
    }
    return cnt;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&p[i].fs,&p[i].se);
    sort(p+1,p+n+1);
    for(int i=1;i<=n;i++) Sum[i]=Sum[i-1]+p[i].se;
    LL ans=0;
    add(p[1].se,p[1].se,e);
    add(p[1].se,1LL,d);
    for(int i=2;i<=n;i++){
        LL tmp=sum(p[i].se,e);//>=p[i].se
        LL num=sum(p[i].se,d);
        ans+=((i-1-num)*p[i].se-(Sum[i-1]-tmp)+tmp-num*p[i].se)*p[i].fs;
        add(p[i].se,p[i].se,e);
        add(p[i].se,1LL,d);
        //cout<<ans<<endl;
    }
    printf("%lld\n",ans);
    return 0;
}
时间: 2024-12-25 21:34:21

POJ1990 MooFest的相关文章

POJ1990 MooFest 树状数组(Binary Indexed Tree,BIT)

N头牛排成一列,每头牛的听力是Vi,每头牛的位置Pi,任意两头牛i,j相互交流时两头牛都至少需要发出声音的大小为max(Vi,Vj) * |Pi-Pj|,求这N头牛两两交流总共发出的声音大小是多少.N,V,P都是1-20000的范围. 这题首先对Vi从小到大进行排序,排序过后就可以依次计算i,将所有比Vi小的牛到i之间的距离之和乘以Vi得到Ri,然后累加Ri就是最终结果.问题是Ri具体该如何求. 假设听力比Vi小的牛并且位置也比Pi小的牛的个数为Ci,并且这些距离之和为Si,听力比Vi小的所有牛

树状数组总结——转

转自:夏天的风 http://blog.csdn.net/shahdza/article/details/6314818#comments 又做了几道树状数组的题,决定放一块儿总结一下:恩,总结一下.. (ps:大牛可以直接跳过...) 这得从一张图说起: 树状数组中用的d[],每个点都有一定的管辖范围: 如d[1]=a[1]; d[2]=a[1]+a[2]; d[3]=a[3]; d[4]=a[1]+a[2]+a[3]+a[4]; 等等: 这样的结构关键是为了,对一个数组内部动态的删除,增加,

MooFest(POJ-1990)(树状数组)

最近学习了一下树状数组,这道题纠结了很久,终究是因为没有明白树状数组怎么用. 感觉网上许多大神都只是讲原理,对于我们这些初学的菜鸟恐怕都被吓跑了. 这里我就以实用主义说一下使用方法(其实我觉得其原理应该能对我们更有启发,也许会带来很多潜在的好处): 这里需要注意的是,bit的实现代码中的bit数组一开始必须清零,这个数组并不是用来储存元素的,而是为实现这个数据结构而存在的.  你需要存储的元素是要通过那个add函数添加的,而求和则是要通过sum函数实现的,而这个bit数组的结构并不是对于一个新手

MooFest POJ1990

题意: 一群牛参加完牛的节日后都有了不同程度的耳聋,第i头??听见别人的讲话,别牛??的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离.现在有n头牛,求他们之间两两交流最少要的音量和. 拿到后很难入手 枚举n^2k肯定是超时的 可以根据所有牛的耳背程度从小到大排序  这样从头开始调用排序好的数据  只要求 当前牛到目前已遍历的所有牛的距离之和(分别处理当前牛左边的数量+右边的数量)  乘 当球牛的耳背程度(因为当球牛的耳背程度是最高的

奶牛集会(MooFest, USACO 2004 Open)

题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为Xi,没有两头奶牛的坐标是相同的.奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出max{Vi; Vj}×|Xi ? Xj | 的音量,其中Vi 和Vj 分别是第i 头和第j 头奶牛的听力.假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少.

POJ 1990 MooFest(树状数组)

                                                                    MooFest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7077   Accepted: 3181 Description Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest"

POJ 1990 MooFest

MooFest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5339   Accepted: 2300 Description Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves

POJ1990--POJ 1990 MooFest(树状数组)

Time Limit: 1000MSMemory Limit: 30000K Total Submissions: 8141Accepted: 3674 Description Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves a variety of e

bzoj3378[Usaco2004 Open]MooFest 狂欢节*

bzoj3378[Usaco2004 Open]MooFest 狂欢节 题意: n只奶牛,第i只听力为vi,坐标为xi,两只奶牛聊天时音量是max(vi,vj)*abs(xi-xj).求n(n-1)/2对奶牛的音量和.n≤20000. 题解: 首先所有奶牛按x排序,记录其位置,接着再按它们音量升序排序依次插入树状数组.维护两个树状数组,一个用来求位置比某奶牛大的坐标和和奶牛数,另一个用来求位置比某奶牛小的坐标和和奶牛数.对于每个插入的奶牛i,对答案的贡献是vi*位置比它大的坐标和与奶牛数*该奶牛