zoukankan      html  css  js  c++  java
  • POJ--1990(排序+树状数组)

    地址:http://poj.org/problem?id=1990

    题意:

    给出n只,每只两个属性:

    v,x

    每两只的和为:sum=max(v1,v2)*fabs(x1-x2),求所有n*(n-1)/2对的和

    解析:

    对v值进行从小到大排序,那么对于当前羊的v值,它之前的羊都要乘这个v。

    那么对于当前羊,需要求它之前的sum值。v这个问题已经解决,那么x呢?

    它之前的羊的x,要么比它大,要么比它小,所以对于这个fabs的求法是不同的,需要解决这个问题。

    引入两个树状数组,num[i]:比i值小的x的个数  ds[i]:比i小的x的和。

    对于当前羊 i :

    ll sx=getsum(st[i].x,num);

    ll sm=getsum(st[i].x,ds);

    求出了比羊 i 的 x 的小的x的个数,以及它们的和

    所以对sum的贡献就是:

    ll small=sx*st[i].x-sm;//因为当前羊的x,要被减sx次,所以直接乘sx

    定义tot为羊 i 之前的x总和,那么已知比此羊小的x的和sm,那么自然就求出了比它大的和:

    tot-sm

    那么有:i-1-sx个st[i].x被减掉。总的来说就是:

    ll big=tot-sm-(i-1-sx)*st[i].x;

    剩下的就不解释了,看代码吧:

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e4+100;
    ll num[maxn],ds[maxn];
    int n;
    struct node
    {
        int v,x;
    }st[maxn];
    bool cmp(node a,node b){
        return a.v<b.v;
    }
    ll lowbit(ll x)
    {
        return x&(-x);
    }
    ll getsum(int id,ll c[])
    {
        ll an=0;
        for(int i=id;i>0;i-=lowbit(i))
            an+=c[i];
        return an;
    }
    void update(ll c[],int id,ll x)
    {
        for(int i=id;i<maxn;i+=lowbit(i))
            c[i]+=x;
        return ;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&st[i].v,&st[i].x);
        ll all=0;
        ll tot=0;
        sort(st+1,st+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            ll sx=getsum(st[i].x,num);
            ll sm=getsum(st[i].x,ds);
            ll small=sx*st[i].x-sm;
            ll big=tot-sm-(i-1-sx)*st[i].x;
            all=all+(small+big)*st[i].v;  //记录答案
            tot+=st[i].x;  //更新i之前的和值
            update(ds,st[i].x,st[i].x);//更新比它x小和
            update(num,st[i].x,1);//更新比它x小的数目
        }
        cout<<all<<endl;
    }
  • 相关阅读:
    javascript创建对象的方法--基本模式
    javascript进阶课程--第二章--对象
    JavaScript中的global对象,window对象以及document对象的区别和联系
    onblur 对象失去焦点事件
    php排序
    php数组插入数据
    thinkphp多层volist实现多表查询
    数据转换
    循环赛日程安排问题
    JS中setTimeout()的使用方法具体解释
  • 原文地址:https://www.cnblogs.com/liyexin/p/13090325.html
Copyright © 2011-2022 走看看