题目大意:有若干头牛,每个牛有一个音量值,两头牛能互相听见对方说话需要发出两头牛中音量值较大者的音量*两头牛的距离的音量,求使任意两头牛都互相听见对方需要发出的音量总和。每头牛的音量值可以相同,但坐标不会相同。

思路:如果一个牛a的音量值,对总体所做的贡献为(音量值比它小的在它左侧的牛的数量*Xa-音量值比它小的在它左侧的牛的坐标和)*a的音量值+(音量值比它小的在它右侧的牛的坐标和-音量值比它小的在它右侧的牛的数量*Xa)*a的音量值。

先按每头牛的音量值进行排序,就可以统计出音量值比某头牛小的牛的个数,以及这些牛的坐标值之和。搞两个树状数组,第一个树状数组用来维护在一只牛左侧的音量值比它小的牛的个数,右侧的根据左侧的也容易求出。第二个树状数组维护一只牛左侧的音量值比它小的所有牛的坐标值之和,右侧的根据左侧的也容易求出。

按音量值从小到大遍历所有牛,对每个牛a,第一个树状数组更新add(Xa,1),表示第Xa位置多了1个牛,求音量值比它小的在它左侧的牛的数量则sum(Xa-1),第二个树状数组更新add(Xa,Xa),表示第Xa位置为坐标值和贡献了Xa,音量值比它小的在它左侧的牛的坐标和则sum(Xa-1)即可。

代码:

//POJ.1990
//Author: Prgl
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) typedef long long ll;
typedef pair<int, int>P;
typedef vector<int>vec; #define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 2e4 + 1; struct BIT {
ll bit[maxn + 1] , n;
void init(int k) { memset(bit, 0, sizeof(bit)); n = k; }
ll sum(ll i)
{
ll s = 0;
while (i > 0)
{
s += bit[i];
i -= i & (-i);
} return s;
}
void add(ll i, ll x)
{
while (i <= n)
{
bit[i] += x;
i += i & (-i);
}
}
}; struct C {
C() = default;
C(int a, int b, int c = -1) :vol(a), x(b), id(c) { }
int vol, x, id;//id为按音量排序后的序号
}; int N;
C cow[20001];
BIT bt1, bt2;
ll xsum[20001]; bool cmp1(C a, C b)
{
return a.vol < b.vol;
} bool cmp2(C a, C b)
{
return a.x < b.x;
} void solve()
{
bt1.init(20001);
bt2.init(20001);
ll res = 0;
sort(cow, cow + N, cmp1);//按音量排序,序号即为所有音量小于它的牛的数量
cow[0].id = 0;
xsum[0] = 0;
for (int i = 1; i <= N; i++)
{
cow[i].id = i;//音量值相同的两头牛id会不同,从而所有音量小于它们的牛的数量也不同,不会出现重复统计的情况
xsum[i] = xsum[i - 1] + cow[i - 1].x;//所有音量小于牛i的所有牛的坐标之和
}
for (int i = 0; i < N; i++)
{
ll x = cow[i].x, vol = cow[i].vol, id = cow[i].id;
ll l = bt1.sum(x - 1);//该牛左侧音量小于它的牛的数量
ll r = id - l;//右侧的
bt1.add(x, 1);//坐标x位置更新1牛
bt2.add(x, x);//坐标x位置更新1牛的坐标值
ll sumf = bt2.sum(x - 1), sumb = xsum[id] - bt2.sum(x - 1); //sumf:该牛左侧音量小于它的牛的坐标之和,sumb:右侧的
res += (l - r) * x * vol + (sumb - sumf) * vol;
}
cout << res << endl;
} int main()
{
IOS;
cin >> N;
for (int i = 0; i < N; i++)
{
int vol, x;
cin >> vol >> x;
cow[i] = C(vol, x);
}
solve(); return 0;
}

POJ1990 题解的更多相关文章

  1. POJ1990:MooFest——题解

    http://poj.org/problem?id=1990 题目大意:定义一对在树轴上的点,每对点产生的值为两点权值最大值*两点距离,求点对值和. 显然n*n复杂度不行,我们需要用树状数组维护两个东 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. ansible roles实践——安装java

    [root@master] /etc/ansible$ cat roles/java/tasks/main.yml ---- name: unzip jdk unarchive: src=jdk-8u ...

  2. 计算机/linux启动过程

    开机过程指的是从打开计算机电源直到LINUX显示用户登录画面的全过程. 分析LINUX开机过程也是深入了解LINUX核心工作原理的一个很好的途径. 计算机开机过程是一个非常复杂的过程,想真正理解透彻并 ...

  3. dubbo-gateway 高性能dubbo网关

    dubbo-gateway dubbo-gateway 提供了http协议到dubbo协议的转换,但[并非]使用dubbo的[泛化]调用(泛化调用性能比普通调用有10-20%的损耗,通过普通异步的调用 ...

  4. IP:网络上的击鼓传花

    链接,而不是直达 在之前<听说你很懂 DNS?>中我们分析过用户在浏览器里面输入 www.baidu.com 后,浏览器如何通过 DNS 解析拿到 IP 地址,然后请求该 IP 地址获取网 ...

  5. 近期Android学习II

    一晃眼又过了5天,这几天的学习有些杂乱,半年在家没运动,返校了准备慢慢恢复运动,身体才是革命的本钱~ 四天跑了三回步,每次都死亡喘息= = 这几天的学习重点总归还是放在Android上了,前面31天连 ...

  6. 学习JAVAWEB第一天

    第一天:单元测试(junit)黑盒测试:不需要写代码,给输入值,看程序能否给出期望值白盒测试:需要写代码,关注程序的具体执行流程junit使用步骤:步骤1:定义一个测试类建议类名,被测试类名后面加一个 ...

  7. JAVA boolean 类型

    boolean 类型用来存储布尔值,在java中布尔值只有2个,true和false. boolean flag=true; flag=false;

  8. 转载_最值得阅读学习的10个C语言开源项目代码

    "源代码面前,了无秘密",阅读优秀代码无疑是开发人员得以窥见软件堂奥而登堂入室的捷径.本文选取10个C语言优秀开源项目的代码作为范本,分别给予点评,免去东搜西罗之苦,点赞!那么问题 ...

  9. Windows服务调用Office时,未将对象引用的实例

    Windows键+R键                         回车 输入:comexp.msc -32               回车 点击控制台根节点--组件服务--计算机--我的电脑- ...

  10. JavaWeb项目根路径问题

    jsp中获取项目根路径: 方法① 最顶部增加代码: <% String path = request.getContextPath(); String basePath = request.ge ...