MooFest POJ1990

题意:

一群牛参加完牛的节日后都有了不同程度的耳聋,第i头??听见别人的讲话,别牛??的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。

拿到后很难入手 枚举n^2k肯定是超时的

可以根据所有牛的耳背程度从小到大排序  这样从头开始调用排序好的数据  只要求 当前牛到目前已遍历的所有牛的距离之和(分别处理当前牛左边的数量+右边的数量)  乘 当球牛的耳背程度(因为当球牛的耳背程度是最高的 所以无需考虑别的牛的耳背程度)

求和问题用树状数组来处理比较快

该题采用两个树状数组  一个为牛的数量  一个为牛的距离  !!

并且求所有元素两两的关系值得学习  只要一次遍历就可以了   不断求当前的与 之前 所有的即可

在结构体内部定义 比较函数 比cmp要快!!!!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 20005

struct node
{
    long long x,v;
    bool operator<(const node &a)const
    {
        return v<a.v;
    }
}s[N];

long long c[2][N];

int lowbit(int i)
{
    return i&-i;
}
void update(int x,long long v,int d)
{
    for(int i=x;i<N;i+=lowbit(i))
        c[d][i]+=v;
}

long long sum(int x,int d)
{
    long long ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        ans+=c[d][i];
    return ans;
}

int main()
{
        int n;
        scanf("%d",&n);
        memset(c,0,sizeof(c));
        //memset(s,0,sizeof(s));
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&s[i].v,&s[i].x);
        }
        sort( s+1,s+n+1 );
        long long ans=0,a,b;
        for(int i=1;i<=n;i++)
        {
            a=sum( s[i].x ,0 );//在此前牛左边的 牛的个数
            b=sum ( s[i].x,1 );//此前牛左边 牛的距离和
            ans+= ( a*s[i].x-b+  sum(20000,1)-b-(i-a-1)*s[i].x   ) *s[i].v;
            update( s[i].x,1,0  );
            update( s[i].x , s[i].x  ,1);
        }
        printf("%lld\n",ans);

        return 0;
}

原文地址:https://www.cnblogs.com/bxd123/p/10357669.html

时间: 2024-12-25 21:34:35

MooFest POJ1990的相关文章

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

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

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小的所有牛

POJ1990 MooFest

题解: 将耳背程度排序,那么对于每次新增一头牛时,只需要算出有前面有多少头牛的距离x比它小以及总和,还有多少头牛的距离x比它大以及总和,就可以计算了. 用2个树状数组维护 一个维护和,一个维护数目 代码: #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<map> #include<set> using namespac

奶牛集会(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*位置比它大的坐标和与奶牛数*该奶牛

poj1990 树状数组

1990 题意: 每头牛有两个属性v,x,计算sigma(max(v[i],v[j])*abs(x[i]-x[j]))1<=i<j<=n 分析:对于max函数我们可以按v的值从小到大排序则ans = sigma(v[j]*abs(x[i]-x[j]))1<=i<j<=n且v[i]<=v[j] 那么如何处理abs函数呢?分开来讨论 ans  = sigma(v[j]*(x[i]-x[j]))    x[i]>=x[j]    + sigma(v[j]*(x[j