第一次写博客 ,请多指教!

翻了翻前面的题解发现都是用树状数组来做,这里更新一个 线段树+离散化的做法:

其实这道题是没有必要用线段树的,树状数组就能够解决。但是个人感觉把线段树用熟了会比树状数组更有优势一点

不多废话 

http://codeforces.com/contest/1311/problem/F 题目链接

题意是 给你一堆点的位置和他们运动的速度(可正可负),然后时间无限往后推的情况下问你他们之间所有点的最小距离之和。(不明白自行读题)

n的范围是2,200000; 显然单纯的一个一个看是不行的,那么自然想到用树状数组或者线段树来做。

接着可以想到

1.当两个点的位置xi ,xj满足 xi<xj 并且两个点的速度满足vi <=vj时 他们之间的最短距离一定是当前距离即xj与xi之差。

2.其余情况最短距离均为零(这一点很容易想)

那么就好办了 

思路就是

1.先对每个点对按照位置从小到大进行排序

2.按照位置从前到后遍历这些点,进行建树。由当前点的速度确定在数组中的位置。

3.建树时每更新一个点之前可以求出这个点对答案的贡献 即:

ans+=(数组中位于当前点前面的点的数量(速度小于当前点速度的点的数量)×当前点的位置)- 前面所有点的位置值的和。

代码中的公式为 ans+=s[i].x*querye(1,x,1,n,1)-query(1,x,1,n,1);

由于是按照位置从前到后的顺序上树的,所以不必担心出现比当前点位置靠后的点;

而关于 统计速度小于当前点速度的点的数量 维护了一个he数组 查询用querye函数,而前面所有点的位置值的和则是最一般的线段树查询。

至于速度给的数据范围有点大,可以使用离散化将他们集中起来,以便作为下标进行更新。

上代码 (代码虽然看起来不是很简短但是基本都是模块化操作,耐心看下来就会感觉很容易理解)

https://www.cnblogs.com/LH2000/category/1656597.html  这里有一些本人写的相关模板函数,可以用作参考。

 #include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rush! ios::sync_with_stdio(false);cin.tie(0);
const int inf = 0x3f3f3f3f;
const long long linf = 0x3f3f3f3f3f3f3f3f;
const int maxn=;
long long tree[maxn<<]; //线段树
long long lsh[]; //离散化 数组
long long he[maxn<<];
struct trees{
long long x, v;
}s[];
bool cmp(const trees &x,const trees &y)
{
return x.x<y.x;
}
void pushup(int rt)
{
tree[rt]=tree[rt<<]+tree[rt<<|]; //用子节点更新父节点的位置值
he[rt]=he[rt<<]+he[rt<<|]; //用子节点更新父节点数量值
} void update(long long p,long long add,int l,int r,int rt) //上树
{
if(l==r)
{
tree[rt]+=add;//更新位置值
he[rt]++;//更新数量值
return;
}
int m=(l+r>>);
if(p<=m) update(p,add,lson);
else update(p,add,rson);
pushup(rt);
} long long query(int L,int R,int l,int r,int rt) //查询速度小于当前点速度的元素位置值的和
{
if(L<=l&&r<=R)
{
return tree[rt];
}
int m=(l+r)>>;
long long ret=;
if(L<=m) ret+=query(L,R,lson);
if(R>m) ret+=query(L,R,rson);
return ret;
}
long long querye(int L,int R,int l,int r,int rt) //查询速度小于当前点速度的元素数量
{
if(L<=l&&r<=R)
{
return he[rt];
}
int m=(l+r)>>;
long long ret=;
if(L<=m) ret+=querye(L,R,lson);
if(R>m) ret+=querye(L,R,rson);
return ret;
} int main()
{
rush! //加速流
int n;
cin>>n;
for(int i=;i<=n;i++)
{
cin>>s[i].x;
}
for(int i=;i<=n;i++){
cin>>s[i].v;
lsh[i]=s[i].v;
}
sort(lsh+,lsh+n+); //离散化排序
sort(s+,s+n+,cmp);
int cnt=unique(lsh+,lsh+n+)-lsh-; //离散化数数
long long ans=;
for(int i=;i<=n;i++)
{
long long x=lower_bound(lsh+,lsh+cnt+,s[i].v)-lsh; //离散化
ans+=s[i].x*querye(,x,,n,)-query(,x,,n,);
update(x,s[i].x,,n,); //上树
}
cout<<ans<<endl;
}

Codeforces Round #624 (Div. 3) F. Moving Points 题解的更多相关文章

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

    题意:给定n个点的初始坐标x和速度v(保证n个点的初始坐标互不相同), d(i,j)是第i个和第j个点之间任意某个时刻的最小距离,求出n个点中任意一对点的d(i,j)的总和. 题解:可以理解,两个点中 ...

  2. Codeforces Round #624 (Div. 3) F

    题意: 给出n的质点,带着初位置和速度: 如果中途两点可以相遇dis(i,j)=0: 如果不可以相遇,mindis(i,j): 求n个点的两两质点最小dis(i,j)之和 思路: 因为当初位置x和速度 ...

  3. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  4. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  5. Codeforces Round #624 (Div. 3)(题解)

    Codeforces Round #624 (Div.3) 题目地址:https://codeforces.ml/contest/1311 B题:WeirdSort 题意:给出含有n个元素的数组a,和 ...

  6. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  7. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  8. Codeforces Round #609 (Div. 2)前五题题解

    Codeforces Round #609 (Div. 2)前五题题解 补题补题…… C题写挂了好几个次,最后一题看了好久题解才懂……我太迟钝了…… 然后因为longlong调了半个小时…… A.Eq ...

  9. Codeforces Round #624 (Div. 3)(题解)

    A. Add Odd or Subtract Even 思路: 相同直接为0,如果两数相差为偶数就为2,奇数就为1 #include<iostream> #include<algor ...

随机推荐

  1. VMware复制Linux虚拟机后网络配置

    1.启动虚拟机,点击我已复制 点击已复制后,VMware将会为重置虚拟机网卡mac地址. 2.修改网卡mac地址 3.ifconfig显示网卡名称与配置不一致处理 Centos6中ifconfig显示 ...

  2. Linux的那些事-系统启动(增加开机启动项)

    1   /etc/init.d 2   /etc/inittab 3   /etc/rc.d/init.d  1.   /etc/init.d 是一般开机的启动服务存放在这个目录下,至于实现机制,其实 ...

  3. 将你的Archlinux打造成路由器

    弄了一块J2900双千兆网口的工控板回来(奇怪的型号)当软路由用,无奈我又想各种皮,还想装桌面环境配VNC,而且我还对虚拟机不感冒(况且这U还不支持直通),只得放弃所有路由器系统.作为一名Arch铁粉 ...

  4. JS生成全局唯一标识符(GUID,UUID)的方法

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...

  5. JS获取最近三个月日期范围

    function getLast3Month() { var now = new Date(); var year = now.getFullYear(); var month = now.getMo ...

  6. k8s~部署EFK框架

    EFK,ELK都是目前最为流行的分布式日志框架,主要实现了日志的收集,存储,分析等,它可以与docker容器进行结合,来收集docker的控制台日志,就是stdout日志. elasticsearch ...

  7. vue目录结构熟悉

    给项目的入口文件做点小改变: [补充:编辑器建议使用vscode,我还没装,暂时先用phpstorm] 打开 APP.vue 文件,代码如下(解释在注释中) <!-- 展示模板 --> & ...

  8. 解决React路由URL中hash(#)部分的显示 、browserHistory打包后浏览器刷新页面出现404的问题

    摘要 在React项目中,我们需要采用它的路由库React-Router来进行页面跳转,React会根据路由URL来判断是哪个页面.常见的的URL有两种显示方式,一种是hashHistory的形式,形 ...

  9. iOS编程实战 — 新的UI范式

    iOS 7给苹果设备带来了全新的用户界面(UI).iOS 7在UI上的变化是自其诞生以来最大的.iOS 7专注于三个重要的特点:清晰.依从和层次.理解这三个特点很重要,因为这有助于设计跟原生的系统内置 ...

  10. window 下如何恢复被删除的mysql root账户及密码(mysql 8.0.17)

    不久前自学完完sql,下了mysql8.0.17,安装配置好后探索着,想着用root账户登上去能不能删除root账户呢,然后就想给自己一巴掌,,, 如何快速恢复root: 1.关闭mysql服务:wi ...