详细讲解Codeforces Round #624 (Div. 3) F. Moving Points

题意:给定n个点的初始坐标x和速度v(保证n个点的初始坐标互不相同), d(i,j)是第i个和第j个点之间任意某个时刻的最小距离,求出n个点中任意一对点的d(i,j)的总和。
题解:可以理解,两个点中初始坐标较小的点的速度更大时,总有一个时刻后面的点会追上前面的点,d(i,j) =0。
否则,即后面的点的速度 <= 前面的点的速度时,两点之间的距离只会越来越大,d(i,j) = abs(xi - xj) (初始距离)。
可以用直线来辅助理解:x = xi + v*t,横轴为t,纵轴为x,若两直线交点t值大于等于0,则d(i,j) = 0。否则交点t值为负 或者两直线平行时,d(i,j)=初始距离。

所以,立即会想到对点按初始坐标排序,遍历每个点,计算出前面点中 速度小于等于 当前点的 所有点与当前点的初始距离总和。n可达2*10^5,需要找O(n log(n))的算法。
若当前点下标为i,前面所有速度不大于当前点的点下标为j1,j2,...,相当于求(x[i]-x[j1])+(x[i]-x[j2])+(x[i]-x[j3])... = num * x[i] - sum(x[j])。即需要使用一个数据结构来维护前面速度较小点的数量 和 初始距离x的总和。
最佳选择就是树状数组,按初始坐标递增的顺序依次添加点的信息,一个树状数组记录小于等于当前速度的点的个数,另一个记录这些点的初始距离总和。
由于速度范围比较大,需要进行离散化处理,即把n个速度离散成n_个下标,树状数组正好对应这个下标。
详细见代码和注释如下:
#include<cstdio>
#include<utility> //pair
#include<algorithm> //sort
#include<vector> //lower_bound, unique
using namespace std; const int maxn = 2e5 + ;
pair<int, int>a[maxn]; //存所有点的(初始坐标,速度)
int v[maxn], n; //所有点的速度,点的个数 long long s1[maxn], s2[maxn]; //两个树状数组
void add(int i, int x) {
while (i <= n) {
s1[i]++; //s1存个数,每次增加1
s2[i] += x; //s2存初始坐标x的总和,每次增加x
i += i & (-i);
}
} long long getSum(long long s[], int i) {
long long res();
while (i > ) {
res += s[i];
i -= i & (-i);
}
return res;
} int main() {
scanf("%d", &n);
for (int i = ; i <= n; i++)scanf("%d", &a[i].first);
for (int i = ; i <= n; i++) {
scanf("%d", v + i);
a[i].second = v[i];
}
sort(a + , a + n + );
sort(v + , v + n + );
int *vend = unique(v + , v + n + ); //速度离散化为 v[1]到v[vend-1 - v]
long long ans = 0LL;
for (int i = ; i <= n; i++) { //按x递增顺序向树状数组中添加点的信息,初始两个树状数组都为空
//得到x第i小的点 的v值 在v数组中对应的下标pos
int pos = lower_bound(v + , vend, a[i].second) - v;
//得到速度小于等于a[i].second的点的个数和x总和
long long sum1 = getSum(s1, pos), sum2 = getSum(s2, pos);
ans += sum1 * a[i].first - sum2; //num * x[i] - num个x[j]的和。(对所有的x[j]<x[i])
add(pos, a[i].first);
}
printf("%lld", ans);
return ;
}
详细讲解Codeforces Round #624 (Div. 3) F. Moving Points的更多相关文章
- Codeforces Round #624 (Div. 3) F. Moving Points 题解
第一次写博客 ,请多指教! 翻了翻前面的题解发现都是用树状数组来做,这里更新一个 线段树+离散化的做法: 其实这道题是没有必要用线段树的,树状数组就能够解决.但是个人感觉把线段树用熟了会比树状数组更有 ...
- 详细讲解Codeforces Round #624 (Div. 3) E. Construct the Binary Tree(构造二叉树)
题意:给定节点数n和所有节点的深度总和d,问能否构造出这样的二叉树.能,则输出“YES”,并且输出n-1个节点的父节点(节点1为根节点). 题解:n个节点构成的二叉树中,完全(满)二叉树的深度总和最小 ...
- Codeforces Round #624 (Div. 3) F
题意: 给出n的质点,带着初位置和速度: 如果中途两点可以相遇dis(i,j)=0: 如果不可以相遇,mindis(i,j): 求n个点的两两质点最小dis(i,j)之和 思路: 因为当初位置x和速度 ...
- Codeforces Round #624 (Div. 3)(题解)
Codeforces Round #624 (Div.3) 题目地址:https://codeforces.ml/contest/1311 B题:WeirdSort 题意:给出含有n个元素的数组a,和 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- Codeforces Round #501 (Div. 3) F. Bracket Substring
题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- Codeforces Round #624 (Div. 3)(题解)
A. Add Odd or Subtract Even 思路: 相同直接为0,如果两数相差为偶数就为2,奇数就为1 #include<iostream> #include<algor ...
随机推荐
- 尼姆博弈+SG函数
博弈这个东西真的很费脑诶.. 尼姆博奕(Nim Game):游戏者轮流从一堆棋子(或者任何道具)中取走一个或者多个,最后不能再取的就是输家.当指定相应数量时,一堆这样的棋子称作一个尼姆堆 当n堆棋子的 ...
- asp获取隐藏域的json 并解析
方法粗糙,适用度适中. var data2 = document.getElementById("hd_data02"); var val = data2.value; var o ...
- 什么是ip地址、子网掩码、网关和DNS?
什么是ip地址? IP是32位二进制数据,通常以十进制表示,并以“.”分隔.IP地址是一种逻辑地地址,用来标识网络中一个个主机,IP有唯一性,即每台机器的IP在全世界是唯一的. IP地址=网络地址+主 ...
- 安装Eclipse activity插件 报异常 Cannot complete the install because one or more required items could not be
下载插件:Activiti Designer 5.17 2)安装过程中错误处理 a.错误: Cannot complete the install because one or more requir ...
- netty EventLoop线程与当前线程的问题
模拟客户端向服务端发送消息: 客户端部分代码如下,当连接激活触发消息发送,采用线程池的形式,分多个线程向服务端发送同一消息 @Override public void channelActive(Ch ...
- SSH(三)
在Spring中引用属性文件: 优点: 1.防止随意更改jdbc的连接 2.给不懂代码的人使用 步骤: 1.数据库连接信息写在属性文件中 ...
- Sqli-Labs 闯关 less 42-49
Less 42 这一关一进去看着像前面的二次注入.发现也注入不了.. 我们观察代码发现这一关用的是堆叠注入. 登陆的这里可以看到login_password登陆的时候并没有使用mysqli_real_ ...
- 一分钟简单了解 JSON Web Token
JSON Web Token(JWT)是一个开放的标准(RFC 7519),它定义了一个紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息.由于此信息是经过数字签名的,因此可以被验证 ...
- Android头像更换之详细操作
Android开发之头像的更换(拍照,从手机照片中选择) 先说一下昨天未解决的问题:原因是自己在获取对象时,没有将新加的图片属性加到该对象里,导致一直爆空指针异常. 接下来分析一下头像更换的具体操作: ...
- Codeforces_805
A.当l == r时,肯定输出这个数就可以了,当存在两个或两个以上连续的数时,2肯定是最多的数,或最多的数之一. #include<bits/stdc++.h> using namespa ...