您的位置:首页 > 其它

poj1990--我的第一道AC树状数组题

2015-04-11 13:18 204 查看





终于过了这道树状数组的题,虽然最后不得不看一下题解,Fighting!!!

题意说,两牛交流所需的音量为|xi-xj|*max(vi,vj),求所有牛两两交流所需音量的总和

总的来说,就是计算对于每一头加入的牛,算出vi*(xi*比xi小的牛数量-比xi小的牛的x坐标值的和+比xi大的牛的x坐标值的和-xi*比xi大的牛数量),然后加入到音量总和中

首先,把牛按耳背程度从小到大排序;

其次,依次加入每一头牛,对于每一头牛,算出vi*(xi*比xi小的牛数量-比xi小的牛的x坐标值的和+比xi大的牛的x坐标值的和-xi*比xi大的牛数量)(因为该牛比前面的牛的v要大)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

struct Cow
{
    long long v;                       //牛的耳背程度
    long long x;                       //牛的x坐标值
};

Cow cow[20010];
long long count_cow[20010];            //第一个树状数组,记录牛的数量和;
long long distance_cow[20010];         //第二个树状数组,记录牛的距离和;
int n;

bool cmp(Cow a,Cow b)
{
    return a.v<b.v;
}

long long sum(long long *bit,int i)
{
    long long s=0;
    while(i>0)
    {
        s+=bit[i];
        i-=i&-i;
    }
    return s;
}

void add(long long *bit,int i,long long x)
{
    while(i<=20000)
    {
        bit[i]+=x;
        i+=i&-i;
    }
}

int main()
{
    //freopen("1990.txt","r",stdin);
    while(scanf("%d",&n)!=EOF)
    {
        memset(count_cow,0,sizeof(count_cow));
        memset(distance_cow,0,sizeof(distance_cow));
        long long sum_volume=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lld%lld",&cow[i].v,&cow[i].x);
        }
        sort(cow,cow+n,cmp);
        for(int i=0;i<n;i++)
        {
            int left=sum(count_cow,cow[i].x-1);                             //前面加入的牛的x坐标值比该牛小的数量
            int right=sum(count_cow,20000)-sum(count_cow,cow[i].x);         //前面加入的牛的x坐标值比该牛大的数量
            int left_path=sum(distance_cow,cow[i].x-1);                     //比该牛的x坐标值小的x坐标值的总和
            int right_path=sum(distance_cow,20000)-sum(distance_cow,cow[i].x);      //比该牛的x坐标值大的x坐标值的总和
            sum_volume+=cow[i].v*(cow[i].x*left-left_path+right_path-cow[i].x*right);   //计算牛的音量和
            add(count_cow,cow[i].x,1);                                      //表示该牛的x坐标值的count_cow+1;
            add(distance_cow,cow[i].x,cow[i].x);                            //表示该牛的x坐标值的distance_cow+该牛的坐标值
        }
        printf("%lld\n",sum_volume);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: