• 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;
    }
  • 相关阅读:
    微信小程序之界面交互反馈
    微信小程序引入腾讯地图API方法
    微信小程序动态修改页面标题setNavigationBarTitle
    JavaScript中||和&&的运算
    微信小程序 使用include导入wxml文件注意的问题
    idea中文乱码及maven项目配置问题
    Linux常用命令大全
    2018年深圳,武汉房价走势分析
    redis安装,windows,linux版本并部署服务
    dubbo基础学习总结
  • 原文地址:https://www.cnblogs.com/liyexin/p/13090325.html
Copyright © 2020-2023  润新知