\[\texttt{Preface}
\]

赛时,把 " 任意时刻 " 理解成 " 整数时刻 " 了,看起来一脸不可做的亚子,还各种推式子。

话说我为什么觉得 E 比 F 还难。

\[\texttt{Description}
\]

一个坐标轴 \(OX\) 上有 \(n\) 个点,第 \(i\) 个点位于整数点 \(x_i\) ,速度为 \(v_i\) 。

所有点以恒定的速度移动,在时刻 \(t\) ( \(t\) 可以是非整数),第 \(i\) 个点的坐标可以被计算为 \(x_i + t \times v_i\) 。

定义 \(d(i,j)\) 为:任何可能的时刻,第 \(i\) 个点和第 \(j\) 个点的最小可能距离,即

\[\min\limits_{t\in[0,∞)} \{ |(x_i+t \times v_i)-(x_j+t \times v_j)| \}
\]

求 \(\sum\limits_{1 \leq i < j \leq n}d(i,j)\) 。

\[\texttt{Solution}
\]

  • 考虑任意两个点 \(i,j\) ,不妨设 \(x_i \leq x_j\) :
  1. 当 \(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\) 。

  2. 当 \(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)}\) 。

\[\texttt{Code}
\]

#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;
}

\[\texttt{Thanks} \ \texttt{for} \ \texttt{watching}
\]

题解【CF1311F Moving Points】的更多相关文章

  1. [CF1311F] Moving Points - 树状数组

    Solution 按 \(x\) 关键字升序排序,依次枚举每个点 考虑对任意 \(x_j < x_i\),那么当 \(v_j \leq v_i\) 时,它们不会相交,且 \(dis\) 就是它们 ...

  2. F. Moving Points 解析(思維、離散化、BIT、前綴和)

    Codeforce 1311 F. Moving Points 解析(思維.離散化.BIT.前綴和) 今天我們來看看CF1311F 題目連結 題目 略,請直接看原題. 前言 最近寫1900的題目更容易 ...

  3. HDOJ 4717 The Moving Points

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. HDU 4717The Moving Points warmup2 1002题(三分)

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. The Moving Points hdu4717

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. HDU 4717 The Moving Points (三分)

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. HDUOJ---The Moving Points

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. 题解 CF576C 【Points on Plane】

    题解 CF576C [Points on Plane] 一道很好的思维题. 传送门 我们看这个曼哈顿距离,显然如果有一边是按顺序排列的,显然是最优的,那另一边怎么办呢? 假如你正在\(ioi\)赛场上 ...

  9. HDU-4717 The Moving Points(凸函数求极值)

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. 关于mysql8启动后又停止(windows10系统),忘记密码以及密码过期等坑解决办法总结!

    一 我遇到的问题 1 mysql连接不了,mysql服务启动后又马上关闭 2 忘记密码或者重装服务后提示安装的随机密码过期 一个一个来,先看第一个: 1 出现这个情况很大原因是mysql安装目录有多余 ...

  2. PCA技术的自我理解(催眠

    Principal component analysis(PCA) 中文就是主成成分分析.在学数学建模的时候将这分为了评价类的方法(我实在是很难看出来,在机器学习中是属于无监督学习降维方法的一种线性降 ...

  3. 通信协议之Modbus协议(一)

    Modbus通信协议: 简介:Modbus协议是应用于电子控制器上的一种通用语言 通过此协议,控制器相互之间,控制器经由网络(例如以太网) 和其他设备之间可以通信,他已经成为一种通用工业标准,有啦它 ...

  4. PE可执行文件加载器

    PE文件加载器 模仿操作系统,加载pe文件到内存中 该项目主要是为了检测pe的学习程度,是否都完全理解了.当然没有完全理解 实现功能的如下: 模仿操作系统,加载pe文件到内存中,然后执行待执行的pe文 ...

  5. C语言遇到的关于清除标准输入缓冲区的问题[编程入门]

    关于标准输入缓冲区的一个易犯的小错误 之前写了个简易的登录程序,但显然这不像写Java时那么容易(只要思路对,基本没问题).一不留神就出现了小BUG! 以下是错误的源代码: #include < ...

  6. Windows下SVN权限配置

    Windows下SVN权限配置          按照前面的教程装完1.6.1版以后,当svnadmin create D;\svn创建仓库后,应该在仓库目录下的config目录有3个文件— auth ...

  7. JavaScript所有函数和内置方法

    Number isFiniter() 检测传入的的数值是否在无穷大和无穷小之间(有限数字或者是可转换成有限数字)返回true,否则返回false.NaN返回false. isFinite(Number ...

  8. 自己封装的一个Ajax小框架

    在经历了Jsp实训的惨痛教训后,特意花了点时间学习Ajax,学完后自我感觉良好,于是写了如下一个小框架: /** * frameAjax * * 参数: * paramsObj: Json * req ...

  9. Go语言之路—博客目录

    Go语言介绍 为什么你应该学习Go语言? 开发环境准备 从零开始搭建Go语言开发环境 VS Code配置Go语言开发环境 Go语言基础 Go语言基础之变量和常量 Go语言基础之基本数据类型 Go语言基 ...

  10. Linux访问权限控制及时间同步实践

    1.编写脚本/root/bin/checkip.sh,每5分钟检查一次,如果发现通过ssh登录失败 次数超过10次,自动将此远程IP放入Tcp Wrapper的黑名单中予以禁止防问 方式一:脚本+定时 ...