题目链接:https://vjudge.net/problem/CodeChef-TELEPORT

题目大意:

  有\(Q\)个指令,指令为:\(+\) \(x\) \(y\)(在二维平面内添加一个点,坐标为\((x,y)\));或\(?\) \(i\) \(j\)(如果第\(i\)个指令所添加的点和第\(j\)个指令所添加的点联通,则打印 "DA",否则打印 “NET").

  关于联通的定义:如果每个点能到达的区域为\({(a,b):|a-x|+|b-y| \le R}\).如果点\(u\)和点\(v\)联通,点\(v\)和点\(k\)联通,则点\(u\)和点\(k\)联通。

  \(1 \le Q,R,x,y \le 100,000\)

知识点:  线段树、并查集

解题思路:

  易知每个点能到达的区域为一个对角线长度为\(2R\)的正菱形,我们可以通过将其旋转\(45^\circ \)来将其转换成正方形,具体的转化方法为

  \(x' = x + y\)

  \(y' = x - y\)

而该正方形的连通区域也转变成了\({(a',b'):|a'-x'|+|b'-y'| \le R}\).

具体证明:(参考(chao)自官方题解

  \(|x-a|+|y-b| = max(x-a+y-b, x-a+b-y, a-x+y-b, a-x+b-y) = max(|(x+y)-(a+b)|, |(x-y)-(a-b)|) = max(|x'-a'|, |y'-b'|) \le R\)

(转化的部分才是本题的精髓所在)

  转化为正方形之后,对于坐标轴的 \(x\) 轴建立线段树,用\(set\)记录\(x\)在该区间中的中心点所对应\(y\)值及其指令编号。

  添加的时候先查询一下在

\([x-2R,x] \times [y-2R,y], [x-2R,x] \times [y,y+2R], [x,x+2R] \times [y-2R, y], [x,2R] \times [y,y+2R] \)

这\(4\)个正方形区域中有没有点,如果有,则将各个区域中最靠近的点和要添加的点用并查集合并在一起。

  询问的时候只需询问两个点是否并在一起了即可。

  具体实现看代码及注释

AC代码:

 #include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 const int maxn=,RR=;
typedef pair<int,int> P;
set<P> tree[maxn<<]; //(y值,第几次查询)
void update(int pos,int y,int q,int l,int r,int rt){//在pos点插入纵坐标为y,查询编号为q的点
tree[rt].insert(make_pair(y,q));
if(l==r) return;
int m=(l+r)>>;
if(pos<=m) update(pos,y,q,lson);
else update(pos,y,q,rson);
}
int query(int L,int R,int y,int aR,int l,int r,int rt){//查询[L,R]*[y,2*aR]的正方形区域
if(L<=l&&r<=R){
set<P>::iterator it=tree[rt].lower_bound(make_pair(y,)); //找出纵坐标大于或等于y的最小值
if(it != tree[rt].end() &&(it->first <= y+*aR)) return it->second; //返回对应的编号(从1开始)
return ;//否则返回0
}
int m=(l+r)>>;
int ret=;
if(L<=m) ret=max(ret,query(L,min(m,R),y,aR,lson));
if(R>m) ret=max(ret,query(max(L,m+),R,y,aR,rson));
return ret;
} //并查集部分
int par[maxn];
void init(int n){
for(int i=;i<=n;i++) par[i]=i;
}
int finds(int x){
if(par[x]==x) return x;
return par[x]=finds(par[x]);
}
void unite(int x,int y){
int tx=finds(x);
int ty=finds(y);
if(tx==ty) return;
par[tx]=ty;
}
//*******************************************************
int main(){
int Q,R,x,y;
char tmp[];
scanf("%d%d",&Q,&R);
init(Q);
for(int q=;q<=Q;q++){
scanf("%s %d %d",tmp,&x,&y);
int tx=x+y+*R,ty=x-y; //因为后面会查询到[tx-2*R,tx]这个区间,所以我们统一先将其加上2*R,避免出现负数,数组也要相应地开大一点
if(tmp[]=='+'){
int x1=query(tx-*R,tx,ty-*R,R,,maxn,);
int x2=query(tx-*R,tx,ty,R,,maxn,);
int x3=query(tx,tx+*R,ty-*R,R,,maxn,);
int x4=query(tx,tx+*R,ty,R,,maxn,);
if(x1) unite(x1,q);
if(x2) unite(x2,q);
if(x3) unite(x3,q);
if(x4) unite(x4,q);
update(tx,ty,q,,maxn,);
}
else{
if(finds(x)==finds(y)) printf("DA\n");
else printf("NET\n");
}
}
}

     

CodeChef - TELEPORT的更多相关文章

  1. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  2. 批量去除Teleport Pro整站下载文件冗余代码

    teleport pro tppabs标签批量删除 teleport pro tppabs标签批量删除 使 用Teleport Pro下载的网页代码中包含了很多垃圾代码,比如下载的html网页代码中会 ...

  3. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  4. Teleport Ultra/Teleport Pro的冗余代码批量清理方法

    Teleport Pro 是款优秀的网站离线浏览工具(即网站整站下载工具),Teleport Ultra是其增强版,但使用此系列软件下载的离线网页里会包含大量冗余代码(如tppabs),手动去修改工作 ...

  5. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  6. Gravitational Teleport 是一个先进的 SSH 服务器,基于 Golang SSH 构建,完全兼容 OpenSSH

    Gravitational Teleport 是一个先进的 SSH 服务器,可通过 SSH 或者 HTTPS 远程访问 Linux 服务器.其目的是为了替代 sshd.Teleport 可以轻松让团队 ...

  7. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

  8. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  9. CodeChef CBAL

    题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...

随机推荐

  1. 【Linux题目】第六关

    [定时任务规则] 1. 如果在某用户的crontab文件中有以下记录,该行中的命令多久执行一次(RHCE考试题)?( ) 30 4 * * 3 mycmd A. 每小时. B. 每周. C. 每年三月 ...

  2. CSS开发技巧(二):表格合并边框后的单元格宽度计算

    前言: 分离边框模型和合并边框模型是表格的两种模型,它通过以下属性确定: border-collapse:separate(默认值) | collapse | inherit 当采用分离边框模型时,表 ...

  3. python实现二分叉查找

    *二分叉查找就是折半查找 比如12345这几个数字当中找2,他会先找到这五个数字中的中坚的那个与2进行比较,比如中间的3>2他就认为3以后的不用查找了,然后查找3左边的,即123,再把这个分半, ...

  4. windows 7或以上系统的实用小工具,你知道么?

    今晚给大家介绍个实用的好工具,可以做简单的问题记录,再也不用截图加注释这么辛苦了····· 经测试,这东东在win7,2008 及2008R2里适用,也就是说,在win7以上的系统中才有.好了,下面直 ...

  5. Clickhosue 强大的函数,argMin() 和argMax()函数

    说实话,我喜欢Clickhouse 的函数,简单操作,功能强大.今天需要给大家介绍两个函数,argMin(),argMax() 1.argMax():计算 ‘arg’ 最大值 ‘val’ 价值. 如果 ...

  6. django3开发完整博客带评价

    纯django开发最完美博客 2020年5月打造最时尚博客系统教程 为了学习速度,集中精力学习django和博客开发, 没有使用其它框架,也没有使用css预处理等 这样学起来最方便, 博客前后端都完成 ...

  7. vue将后台的值赋给前台

    后台传List到前台: 赋值给table 赋值给form(只能一个个的赋值,对应prop属性) 后台传map到前台:(不需要使用下标取值)

  8. 组合模式(c++实现)

    组合模式 目录 组合模式 定义 动机 UML类图 场景拆解 源码实现 优点 缺点 定义 将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式是的用户对单个对象和组合对象的使 ...

  9. Excel心得

    智能表.数据透视表.分类汇总表是Excel最值得学的技能. 通过插入表,或者快捷键Ctrl+T/Ctrl+L,可以将区域转换为智能表,保证了字段的公式的统一,而且版式自动化处理,一深一浅.Ctrl+Q ...

  10. 简述异步编程&Promise&异步函数

    前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...