题解【CF1311F Moving Points】
\]
赛时,把 " 任意时刻 " 理解成 " 整数时刻 " 了,看起来一脸不可做的亚子,还各种推式子。
话说我为什么觉得 E 比 F 还难。
\]
一个坐标轴 \(OX\) 上有 \(n\) 个点,第 \(i\) 个点位于整数点 \(x_i\) ,速度为 \(v_i\) 。
所有点以恒定的速度移动,在时刻 \(t\) ( \(t\) 可以是非整数),第 \(i\) 个点的坐标可以被计算为 \(x_i + t \times v_i\) 。
定义 \(d(i,j)\) 为:任何可能的时刻,第 \(i\) 个点和第 \(j\) 个点的最小可能距离,即
\]
求 \(\sum\limits_{1 \leq i < j \leq n}d(i,j)\) 。
\]
- 考虑任意两个点 \(i,j\) ,不妨设 \(x_i \leq x_j\) :
当 \(v_i \leq v_j\) 时:
说明点 \(i\) 的速度不比点 \(j\) 快,意味着每过一秒,点 \(i,j\) 的距离会增大 \(v_j-v_i\) ,由于 \(t\times(v_j-v_i) \geq 0\) ,所以点 \(i,j\) 的距离永远不降,故时刻 \(0\) 时,\(d(i,j)\) 最小,此时 \(d(i,j)=x_j-x_i\) 。
当 \(v_i>v_j\) 时:
说明点 \(i\) 的速度比点 \(j\) 快,意味着每过一秒,点 \(i,j\) 的距离会减少 \(v_i-v_j\) ,突然想到小学数学的 追及问题 ,显然可得,在时刻 \(\frac{x_j-x_i}{v_i-v_j}\) 时,点 \(i\) 与点 \(j\) 重合,故 \(d(i,j)=0\) 。
我们发现情况 \(2\) 对答案没有贡献,实际上只是求情况 \(1\) 的贡献,也就是 \(\sum\limits_{x_i \leq x_j \ \& \ v_i \leq v_j}(x_j-x_i)\) 。
然后我们发现这是一个经典的偏序问题,具体的:
我们将所有点按 \(x\) 这一维从小到大排序,就可以直接去掉 \(x_i \leq x_j\) 的偏序关系了。
将 \(v\) 这一维离散化,建立两个 BIT(当然线段树也行),一个用于维护当前扫描到的点中, \(v\) 值在区间内的点的个数,一个用于维护 \(v\) 值在区间内的点的 \(x\) 值和。
接下来我们扫描每个点 \(i\) ,计算将 \(i\) 当成位置靠后的那个点时所产生的贡献,当固定住 \(i\) 时,此时 \(x_i\) 是不变的,我们记 \(v\) 值小于等于 \(v_i\) 的点的数量为 \(c_1\) , \(v\) 值小于等于 \(v_i\) 点的 \(x\) 值和为 \(c_2\) ,贡献为 \(x_i \times c_1-c_2\) ,最后再将点 \(i\) 插入 BIT ,扫描完即可求出答案。
\(\mathcal{O(n \log n)}\) 。
\]
#include<cstdio>
#include<algorithm>
#define RI register int
using namespace std;
namespace IO
{
static char buf[1<<20],*fs,*ft;
inline char gc()
{
if(fs==ft)
{
ft=(fs=buf)+fread(buf,1,1<<20,stdin);
if(fs==ft)return EOF;
}
return *fs++;
}
#define gc() getchar()
inline int read()
{
int x=0,f=1;char s=gc();
while(s<'0'||s>'9'){if(s=='-')f=-f;s=gc();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=gc();}
return x*f;
}
}using IO::read;
const int N=200100;
int n;
struct Node{
int x;
int v;
}a[N];
bool cmp(Node a,Node b)
{
return a.x<b.x;
}
int len,mapval[N];
void discrete() // 离散化
{
sort(mapval+1,mapval+1+len);
len=unique(mapval+1,mapval+1+len)-mapval-1;
}
int Real(int x)
{
return lower_bound(mapval+1,mapval+1+len,x)-mapval;
}
long long c[N][2]; // 0 维是数量 , 1 维是 x 值和
void add(int x,int k,int val)
{
for(;x<=len;x+=x&-x)c[x][k]+=val;
}
long long ask(int x,int k)
{
long long ans=0;
for(;x;x-=x&-x)ans+=c[x][k];
return ans;
}
long long ans;
int main()
{
n=read();
for(RI i=1;i<=n;i++)
a[i].x=read();
for(RI i=1;i<=n;i++)
mapval[++len]=a[i].v=read();
sort(a+1,a+1+n,cmp); // 排序
discrete();
for(RI i=1;i<=n;i++)
a[i].v=Real(a[i].v);
for(RI i=1;i<=n;i++)
{
ans+=a[i].x*ask(a[i].v,0)-ask(a[i].v,1); // 计算
add(a[i].v,0,1),add(a[i].v,1,a[i].x);
}
printf("%lld\n",ans);
return 0;
}
\]
题解【CF1311F Moving Points】的更多相关文章
- [CF1311F] Moving Points - 树状数组
Solution 按 \(x\) 关键字升序排序,依次枚举每个点 考虑对任意 \(x_j < x_i\),那么当 \(v_j \leq v_i\) 时,它们不会相交,且 \(dis\) 就是它们 ...
- F. Moving Points 解析(思維、離散化、BIT、前綴和)
Codeforce 1311 F. Moving Points 解析(思維.離散化.BIT.前綴和) 今天我們來看看CF1311F 題目連結 題目 略,請直接看原題. 前言 最近寫1900的題目更容易 ...
- HDOJ 4717 The Moving Points
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 4717The Moving Points warmup2 1002题(三分)
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- The Moving Points hdu4717
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 4717 The Moving Points (三分)
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDUOJ---The Moving Points
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 题解 CF576C 【Points on Plane】
题解 CF576C [Points on Plane] 一道很好的思维题. 传送门 我们看这个曼哈顿距离,显然如果有一边是按顺序排列的,显然是最优的,那另一边怎么办呢? 假如你正在\(ioi\)赛场上 ...
- HDU-4717 The Moving Points(凸函数求极值)
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
随机推荐
- Leetcode 题目整理-4 Longest Common Prefix & Remove Nth Node From End of List
14. Longest Common Prefix Write a function to find the longest common prefix string amongst an array ...
- TypeScript躬行记(4)——泛型
泛型是程序设计语言中的一种风格或范式,相当于类型模板,允许在声明类.接口或函数等成员时忽略类型,而在未来使用时再指定类型,其主要目的是为它们提供有意义的约束,提升代码的可重用性. 一.泛型参数 当一个 ...
- 用什么库写 Python 命令行程序?看这一篇就够了
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- ATL的GUI程序设计(前言)
前言 也许,你是一个顽固的SDK簇拥者: 也许,你对MFC抱着无比排斥的态度,甚至像我一样对它几乎一无所知: 也许,你符合上面两条,而且正在寻求着一种出路: 也许,你找到了一条出路--WTL,但是仍然 ...
- Codeforces_714_A
http://codeforces.com/problemset/problem/714/A 水,注意K的值. #include <iostream> using namespace st ...
- lua学习之基础概念篇
基础概念 程序块 (chunk) 定义 lua 中的每一个源代码文件或在交互模式(Cmd)中输入的一行代码都称之为程序块 一个程序块就是一连串语句或者命令 lua 中连续的语句不需要分隔符,但为了可读 ...
- Jumpserver:跳板机
简介 jumpserver是github上的一个开源项目,其能有效的对服务器.用户进行分组,实现用户-系统用户-服务器的对应权限控制,并结合审计.日志等功能,据说是 4A 级的专业运维审计系统,系统提 ...
- Go语言实现:【剑指offer】孩子们的游戏
该题目来源于牛客网<剑指offer>专题. 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的 ...
- github三步走(init;add . ;commit -m "提交说明")
掌握以下几点就基本能满足你平时使用了.按这个顺序来1.git安装,已经好了,略 -到这里本地代码推送到远程已经结束了 2.git本地命令操作-shift+右键-git init:初始化git环境-新建 ...
- java8 Stream API笔记
生成Stream Source的方式 从Collection和数组生成 * Collection.stream() * Collection.parallelStream() * Arrays.str ...