CF1311F Moving Points
思路
给出一种不需要脑子的四颗树状数组解法。
这四颗树状数组分别为:一颗维护负数,一颗维护负数个数,一颗维护正数,一颗维护正数个数。
首先考虑没有速度该怎么求。
不妨先按 \(x_i\) 从小到大排序,答案为 \(\sum x_i \times (i-1)-sum_i\),其中 \(sum_i\) 表示 \(\sum_{j=1}^i x_j\)。所以我们不妨先把 \(ans\) 赋值为这个值。
接下来考虑加入速度。
我们只需考虑两种情况:相遇和相离,由于时间无限,所以相遇的情况 \(d_{i,j}\) 一定是 \(0\),而相离后的距离一定大于 \(0\) 时刻的距离,所以 \(d_{i,j}\) 实际只有两种情况:\(0\),\(|x_i-x_j|\)。
我们已经把所有的 \(|x_i-x_j|\) 累加入答案,接下来只需要消去 \(0\) 的贡献即可。
设当前扫到的位置为 \(i\):
- 若 \(v_i>0\),则此时能与 \(i\) 距离为 \(0\) 的点 \(j\) 必定满足 \(v_j>v_i\),这是简单的追及问题。
- 若 \(v_i<0\),则此时能与 \(i\) 距离为 \(0\) 的点 \(j\) 必定满足 \(v_j>0\) 或 \(v_j<v_i\),\(v_j>0\) 是相遇问题,\(v_j<v_i\) 是追及问题。
接下来就可以简单地二维数点了,或者也可以像我一样暴力开四颗树状数组维护。
代码
//A tree without skin will surely die.
//A man without face is invincible.
#include<bits/stdc++.h>
using namespace std;
#define int long long
int const N=2e5+10;
int n,b[N],sum[N],hsum[N];
struct node{int x,v;}a[N];
struct Tree_Array{
int c[N];
#define lowbit(x) (x&-x)
inline void update(int x,int v){while (x<=n) c[x]+=v,x+=lowbit(x);}
inline int query(int x){int res=0;while (x) res+=c[x],x-=lowbit(x);return res;}
}T[5];
inline bool cmp(node a,node b){return a.x<b.x;}
signed main(){
//读入
sort(b+1,b+n+1);int l=unique(b+1,b+n+1)-b-1;//离散化
for (int i=1;i<=n;++i) a[i].v=lower_bound(b+1,b+l+1,a[i].v)-b;
sort(a+1,a+n+1,cmp);int ans=0;
for (int i=1;i<=n;++i) sum[i]=sum[i-1]+a[i].x;
for (int i=n;i>=1;--i) hsum[i]=hsum[i+1]+a[i].x;
for (int i=1;i<=n;++i) ans+=a[i].x*(i-1)-sum[i-1];
int sum0=0,sum=0;
for (int i=1;i<=n;i=i){
int j=i;while (a[j+1].x==a[i].x) ++j;
for (int k=i;k<=j;++k){
if (!b[a[k].v]){
ans-=a[k].x*T[3].query(n)-T[0].query(n);
continue;
}
if (b[a[k].v]>0) ans-=a[k].x*(T[3].query(n)-T[3].query(a[k].v))-(T[0].query(n)-T[0].query(a[k].v));
else ans-=a[k].x*sum0-sum+a[k].x*(T[3].query(n)+(T[4].query(n)-T[4].query(a[k].v)))-(T[0].query(n)+(T[1].query(n)-T[1].query(a[k].v)));
}
for (int k=i;k<=j;++k){
if (!b[a[k].v]){
++sum0;
sum+=a[k].x;
continue;
}
if (b[a[k].v]>0) T[0].update(a[k].v,a[k].x),T[3].update(a[k].v,1);
else T[1].update(a[k].v,a[k].x),T[4].update(a[k].v,1);
}
i=j+1;
}
//输出
return 0;
}
CF1311F Moving Points的更多相关文章
- 题解【CF1311F Moving Points】
\[ \texttt{Preface} \] 赛时,把 " 任意时刻 " 理解成 " 整数时刻 " 了,看起来一脸不可做的亚子,还各种推式子. 话说我为什么觉得 ...
- [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 ...
- HDU-4717 The Moving Points(凸函数求极值)
The Moving Points Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- The Moving Points
Problem Description There are N points in total. Every point moves in certain direction and certain ...
随机推荐
- Windows及eclipse常用快捷键-小彤在努力
Windows快捷键 Ctrl+A:全选 Ctrl+S:保存 Ctrl+Z:撤回 Ctrl+X:剪切 Ctrl+C:复制 Ctrl+V:粘贴 Ctrl+F:查找 Windows+E:打开我的电脑 Al ...
- 【Java SE进阶】Day09 字节流、字符流、I/O操作、属性集
一.I/O概述 1.输入输出 输入:硬盘-->内存 输出:内存-->内存 2.流 字节流:一个字节等于8位 字符流:一个字符=2个字节 二.字节流 1.概述 以字节的方式读取/传输 可以读 ...
- python文件名解析---从文件名获得分类类别
python文件名解析-从文件名获得分类类别 python os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表.列表以字母顺序. listdir()方法 举例说明 lis ...
- Window系统的mysql数据库定时备份
原文:Window系统的mysql数据库定时备份 - Stars-One的杂货小窝 最近老大提到了数据库备份的功能,由于服务器是window系统的,所以研究了下备份的方案,特此记录 主要是实现每天定时 ...
- 网络爬虫之requests模块,自动办公领域之openpyx模块
一.第三方模块的下载与使用 第三方模块:别人写的模块,一般情况下功能都特别强大 我们如果想使用第三方模块,第一次必须先下载,后面才可以反复使用(等同于内置模块) 下载第三方模块的方式 1. pi ...
- error: expected ‘)’ before ‘PRIx64’
打印uint64时编译报错 printf("prefix:0x%"PRIx64"\n",ipv6Prefix); 解决办法:添加头文件 #include < ...
- JavaScript 图像压缩
JavaScript 可以使用类似于 canvas 和 web workers 来实现图像压缩. 使用 canvas,可以将图像绘制到 canvas 上,然后使用 canvas 提供的 toBlob( ...
- Git Rebase和Merge的用法
title: Git Rebase和Merge的用法 categories: 后端 tags: - Git Rebase和Merge是什么? merge和rebase的作用都是合并两个分支,其区别在于 ...
- AtCoder Regular Contest 148 A - mod M
题面 You are given a sequence \(A = (A_1, A_2, ..., A_N)\). You may perform the following operation ex ...
- P1278 单词游戏【题解】(状压dp)
单词游戏 题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍 ...