【cf1046】A. AI robots(动态开点线段树)
题意:
坐标轴上有\(n\)个机器人,每个机器人带有属性\(x,r,q\),分别表示位置、可视半径以及智商。
现在定义智商相近为两个机器人的智商差的绝对值不超过$K。
现在问有多少对机器人,他们在互相的可视范围内并且智商相近。
思路:
一开始没注意到互相在对面的可视范围内,以为是主席树模板题。。。
- 注意到\(K\leq 20\),所以总的有用的智商值为\(40*n\)个。
- 那么我们可以采用动态开点的方法,对于每个智商值,储存存在的区间的位置,这样可以节约空间。
- 对于互相在对方可视范围内,可以先按\(r\)从大到小排序,然后依次处理,当前位置为\(x_i\),那么在\([x_i-r_i,x_i+r_i\)内的机器人都是合法的。
- 那么对于每个机器人,暴力每个智商值,查询在对应区间范围内的机器人个数即可。
时间复杂度约为\(O(nklogn)\),空间复杂度也因为动态开点优化到了\(O(nlogn)\)。
代码如下:
/*
* Author: heyuhhh
* Created Time: 2019/11/12 20:42:29
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 25;
int n, k;
struct node{
int x, r, q;
bool operator < (const node &A) const{
return r > A.r;
}
}a[N];
unordered_map <int, int> mp;
int tot;
int rt[N * 35], ls[N * 35], rs[N * 35], sum[N * 35];
void upd(int &o, int l, int r, int p, int v) {
if(!o) o = ++tot;
if(l == r) {
sum[o] += v;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) upd(ls[o], l, mid, p, v);
else upd(rs[o], mid + 1, r, p, v);
sum[o] = sum[ls[o]] + sum[rs[o]];
}
int query(int o, int l, int r, int L, int R) {
if(!o) return 0;
if(L <= l && r <= R) {
return sum[o];
}
int res = 0, mid = (l + r) >> 1;
if(L <= mid) res += query(ls[o], l, mid, L, R);
if(R > mid) res += query(rs[o], mid + 1, r, L, R);
return res;
}
void run(){
for(int i = 1; i <= n; i++) cin >> a[i].x >> a[i].r >> a[i].q;
sort(a + 1, a + n + 1);
ll ans = 0;
for(int i = 1; i <= n; i++) {
int l = max(0, a[i].x - a[i].r);
int r = a[i].x + a[i].r;
int L = max(0, a[i].q - k);
int R = a[i].q + k;
for(int j = L; j <= R; j++) {
if(mp.find(j) == mp.end()) continue;
ans += query(rt[mp[j]], 0, INF, l, r);
}
if(mp.find(a[i].q) == mp.end()) mp[a[i].q] = ++tot;
upd(rt[mp[a[i].q]], 0, INF, a[i].x, 1);
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n >> k) run();
return 0;
}
【cf1046】A. AI robots(动态开点线段树)的更多相关文章
- CF1045G AI robots(动态开点线段树)
题意 火星上有$N$个机器人排成一行,第$i$个机器人的位置为$x_{i}$,视野为$r_{i}$,智商为$q_{i}$.我们认为第$i$个机器人可以看到的位置是$[x_{i}-r_{i},x_{i} ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- codeforces 915E - Physical Education Lessons 动态开点线段树
题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
随机推荐
- oracle表空间设置自动扩展
开启自动扩展功能语法: alter database datafile '对应的数据文件路径信息' autoextend on; 关闭自动扩展功能语法: alter database datafile ...
- jQuery实现简单的tab切换
html: <section> <nav id="nav"> <a class="on">tab1</a& ...
- 关于Linux下进程的详解【进程查看与管理】
一.关于进程 进程: 已经启动的可执行程序的运行实力 进程的组成:一个进程包含内核中的一部分地址空间和一系列数据结构.其中地址空间是内核标记的一部分内存以供进程使用,而数据结构则用来纪录每个进程的具体 ...
- misc-4-1
记录一题盲水印的misc,缅怀昨天高校运维挑战赛的twocats翻车车 下载下来binwalk一下 然后在里面发现了压缩包,并找到两长一模一样的图片,还要tip.txt Although two da ...
- day83_11_1 阿里配python使用。
一.环境准备. 1.首先需要在支付包中注册开发者模式,并注册沙箱,模拟支付过程. https://openhome.alipay.com/platform/appDaily.htm?tab=info ...
- jenkins传统模式发布istio应用
一.发布金丝雀版本 Pre Setps cd /var/lib/jenkins/workspace/istio-service-user-canary/istio-service-user # 旧版本 ...
- perl: warning: Setting locale failed. 解决
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAG ...
- 【Linux命令】nohup命令用法
nohup命令用法 当我们想将某个脚本或程序运行在后台的时候.我们一般会在程序或脚本后面添加 & 字符来表示在后台运行,但使用& 运行在后台,当我们将shell窗口关闭时,该脚本或程序 ...
- C++入门到理解阶段二基础篇(6)——C++数组
概述 C++ 支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合.数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量. 数组的声明并不是声明一个个单独的变量,比如 numbe ...
- C++值类别, move, perfect forward
推荐看链接顺序看,第一个链接很好地讲述了值类别地特性,图形很好理解.第二个链接介绍常见值类别的示例,帮助熟悉.第三个链接是第二个链接的补充,让你理解为什么需要std::move以及perfect fo ...