【题解】Radio stations Codeforces 762E CDQ分治
虽然说好像这题有其他做法,但是在问题转化之后,使用CDQ分治是显而易见的
并且如果CDQ打的熟练的话,码量也不算大,打的也很快,思维难度也很小
没学过CDQ分治的话,可以去看看我的另一篇博客,是CDQ分治的入门教程
下面是正文:
首先整理一下条件:
每个点有三个属性,x,r,f
统计有多少对点i,j满足 min(ri,rj) >= |xi-xj| 且 |fi-fj| <= k,这样的点对被称作是“坏的”
对r值取min是个烦人的条件,于是我们把点按照r值从大到小排序,按照r值从大到小的顺序依次考虑每个点
这样对于每个点,我们只考虑它之前出现的点,也就是r值比他大的点,和他能不能组成“坏的”点对
这样的话,因为一个点i之前所有的点j的r值都比他大,所以 min(ri,rj) = ri
然后我们重新看一下问题:
按照指定的顺序依次加入点,每次加入一个点i,考虑它之前加入的所有点j,有多少个点满足 |xi-xj| <= ri 且 |fi-fj| <= k
再转化一下:
对于每个点i,考虑有多少个它之前的点j满足 xi-ri <= xj <= xi+ri 且 fi-k <= fj <= fi+k
我们把x和f这两个属性看做二维平面中的横纵坐标,问题就变成了:
向一个平面中添加一个点,查询指定矩形内点的个数
这是一个经典的三维偏序问题,可以用 线段树套线段树 或者 CDQ分治 来做
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cctype>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map> using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXF = ; int n, k; struct Item { // 每个点的信息
int r, x, f;
bool operator<( const Item &rhs ) const {
return r > rhs.r; // 按照r值排序
}
}item[MAXN]; inline int lowbit( int num ) { return num&(-num); }
namespace BIT { // 树状数组相关
int c[MAXF] = {};
void add( int x, int v ) {
for( ; x <= MAXF-; x += lowbit(x) )
c[x] += v;
}
int query( int x ) {
int sum = ;
for( ; x; x -= lowbit(x) )
sum += c[x];
return sum;
}
int query( int l, int r ) {
return query(r) - query(l-);
}
void clear( int x ) {
for( ; x <= MAXF-; x += lowbit(x) )
c[x] = ;
}
} struct Query {
int type, x, y, w;
// type == 1 表示查询 type == 0 表示修改
// w 表示查询对答案的贡献,为1或-1
bool operator<( const Query &rhs ) const {
if( x == rhs.x ) return type < rhs.type;
return x < rhs.x;
}
}query[MAXN*], tmp[MAXN*]; int qidx = ; ll ans = ; void cdq( int L, int R ) { // cdq分治主过程
if( R-L <= ) return;
int M = (L+R)>>; cdq(L,M); cdq(M,R);
int p = L, q = M, o = L;
while( p < M && q < R ) {
if( query[p] < query[q] ) {
if( query[p].type == ) BIT::add( query[p].y, );
tmp[o++] = query[p++];
} else {
if( query[q].type == ) ans += BIT::query( query[q].y ) * query[q].w;
tmp[o++] = query[q++];
}
}
while( p < M ) tmp[o++] = query[p++];
while( q < R ) {
if( query[q].type == ) ans += BIT::query( query[q].y ) * query[q].w;
tmp[o++] = query[q++];
}
for( int i = L; i < R; ++i ) {
if( query[i].type == ) BIT::clear( query[i].y );
query[i] = tmp[i];
}
} int main() {
scanf( "%d%d", &n, &k );
for( int i = ; i < n; ++i )
scanf( "%d%d%d", &item[i].x, &item[i].r, &item[i].f );
sort( item, item+n );
for( int i = ; i < n; ++i ) {
Item &it = item[i]; // 转化为平面上的添加和查询问题
int x1 = it.x-it.r, y1 = max( it.f-k, );
int x2 = it.x+it.r, y2 = it.f+k;
query[qidx++] = (Query){ , x1-, y1-, };
query[qidx++] = (Query){ , x1-, y2, - };
query[qidx++] = (Query){ , x2, y1-, - };
query[qidx++] = (Query){ , x2, y2, };
query[qidx++] = (Query){ , it.x, it.f, }; // 修改的w值没有意义
}
cdq(,qidx);
cout << ans << endl;
return ;
}
【题解】Radio stations Codeforces 762E CDQ分治的更多相关文章
- Radio stations CodeForces - 762E (cdq分治)
大意: 给定$n$个三元组$(x,r,f)$, 求所有对$(i,j)$, 满足$i<j, |f_i-f_j|\le k, min(r_i,r_j)\ge |x_i-x_j|$ 按$r$降序排, ...
- Codeforces 669E cdq分治
题意:你需要维护一个multiset,支持以下操作: 1:在某个时间点向multiset插入一个数. 2:在某个时间点在multiset中删除一个数. 3:在某个时间点查询multiset的某个数的个 ...
- Tufurama CodeForces - 961E (cdq分治)
题面 One day Polycarp decided to rewatch his absolute favourite episode of well-known TV series " ...
- AI robots CodeForces - 1045G (cdq分治)
大意: n个机器人, 位置$x_i$, 可以看到$[x_i-r_i,x_i+r_i]$, 智商$q_i$, 求智商差不超过$k$且能互相看到的机器人对数. 这个题挺好的, 关键是要求互相看到这个条件, ...
- BZOJ2244 [SDOI2011]拦截导弹 【cdq分治 + 树状数组】
题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其 ...
- CodeForces - 762E:Radio stations (CDQ分治||排序二分)
In the lattice points of the coordinate line there are n radio stations, the i-th of which is descri ...
- codeforces 762E(cdq分治)
题意: n个电台,每个电台有三个属性xi, ri, fi.分别代表电台的坐标,电台的播报范围,以及播报的频率. 对于一对电台i, j,若min(ri, rj) >= |xi - xj|,那么他们 ...
- Codeforces 1093E Intersection of Permutations [CDQ分治]
洛谷 Codeforces 思路 一开始想到莫队+bitset,发现要T. 再想到分块+bitset,脑子一抽竟然直接开始写了,当然也T了. 最后发现这就是个裸的CDQ分治-- 发现\(a\)不变,可 ...
- Codeforces 1045G AI robots [CDQ分治]
洛谷 Codeforces 简单的CDQ分治题. 由于对话要求互相看见,无法简单地用树套树切掉,考虑CDQ分治. 按视野从大到小排序,这样只要右边能看见左边就可以保证互相看见. 发现\(K\)固定,那 ...
随机推荐
- java基础-Comparator接口与Collections实现排序算法
java 排序Comparable和Comparator使用 java提供了两个排序用的接口Comparable和Comparator,一般情况下使用区别如下: Comparable 接口用于类的固定 ...
- 【Linux 运维】linux系统关机、重启、注销命令
linux 关机.重启.注销命令: 关机命令: shutdown -h now 立刻关机(生产常用) shutdown -h +1 一分钟后关机 ( shutdown -c 可以将 ...
- Appium基础环境搭建(windows)---基于python
1 JDK安装 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装注意:安装 ...
- net::ERR_ABORTED ,引入js文件出现报错的解决方法
在head头里面添加 <mvc:annotation-driven enable-matrix-variables="true"></mvc:annotation ...
- 在linux下PHP和Mysql环境搞事情
研发部门同事开发了一个接口管理辅助工具Shepherd,要求搭建在内网环境中,遇到点小问题记一下. 将开发的文件上传只web目录下,更改数据库ip,可以正常打开 登陆用户信息,此时需要连接数据库来验证 ...
- StrBlobPtr类——weak_ptr访问vector元素
#include <iostream> #include <memory> #include <string> #include <initializer_l ...
- python异步初步窥探
1.异步之难:因为其执行吮吸不可预料,当下正要发生什么事件不可预料. 程序下一步行为往往依赖上一步值执行结果,如何知晓上次异步调用已完成并获取结果, 回调成了必然选择,那又 ...
- Agile.Net 组件式开发平台 - 驱动开发示例
首先讲一下概念,此驱动非彼驱动.在Agle.Net中我们将组件规划成两种类型,一种是基于业务的窗体组件,一种是提供扩展功能的驱动组件. 打个比方例如一般系统中需要提供身份证读卡功能,然而市面上有很多种 ...
- java 基础 --int 和Integer的区别
感到脸红:int是整形 -128~127 Integer是正整型,你怎么会想到这样的回答,妈的,有脑子吗?!!! 1,int是基本数据类型,初始为0,Integer为封装类,初始为null ①无论如何 ...
- 特殊符号存入mysql数据库时报错:Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F的解决方法
问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varchar,字符编码utf-8.部分插入成功,部分插入失败,报错如标题. 在网上查询,有人说是编码问题,建议修改编码格式,比如改 ...