题目链接: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. 使用spring boot创建fat jar APP

    文章目录 介绍 build和run fat jar和 fat war 更多配置 介绍 在很久很很久以前,我们部署web程序的方式是怎么样的呢?配置好服务器,将自己写的应用程序打包成war包,扔进服务器 ...

  2. 广深小龙-基于unittest、pytest自动化测试框架之demo来学习啦!!!

    基于unittest.pytest自动化测试框架之demo,赶紧用起来,一起学习吧! demo分为两个框架:①pytest    ②unittest demo 中 包含 web.api 自动化测试框架 ...

  3. vue与众不同的学习方式,让她年薪200多万

    学习vue正确思路,是先学vue-cli,再学vue.js单文件引用的用法,这样会在极短时间内撤底撑握vue,如果先学vue.js单文件用法,再去学vue-cli4,可以说是重新学vue,,,,难处大 ...

  4. 【Linux题目】第五关

    1. 如何取得/etiantian文件的权限对应的数字内容,如-rw-r-r 为644,要求使用命令取得644或0644这样的数字. 解答: 方法1:用sed获取stat filename里的属性值 ...

  5. 【Linux常见命令】alias命令

    alias命令用于查看和设置指令的别名. 用户可利用alias,自定指令的别名. 若仅输入alias,则可列出目前所有的别名设置. alias的效力仅及于该次登入的操作.若要每次登入是即自动设好别名, ...

  6. 09-5.部署 EFK 插件

    09-5.部署 EFK 插件 EFK 对应的目录:kubernetes/cluster/addons/fluentd-elasticsearch $ cd /opt/k8s/kubernetes/cl ...

  7. 多线程——继承Thread 类和实现Runnable 接口的区别

    java中我们想要实现多线程常用的有两种方法,继承Thread 类和实现Runnable 接口,有经验的程序员都会选择实现Runnable接口 ,其主要原因有以下两点: 首先,java只能单继承,因此 ...

  8. qemu-img压缩磁盘操作

    2019独角兽企业重金招聘Python工程师标准>>> qemu-img convert -c -f qcow2 -O qcow2 /data/data1.disk /opt/dat ...

  9. C# 多线程(18):一篇文章就理解async和await

    目录 前言 async await 从以往知识推导 创建异步任务 创建异步任务并返回Task 异步改同步 说说 await Task 说说 async Task 同步异步? Task封装异步任务 关于 ...

  10. BSGS 和扩展

    BSGS BSGS,全称叫 BabyStepGiantStep,也就是大步小步 其实还是比较暴力的 它可以\(O(\sqrt p)\)的复杂度内解出: \[a^x\equiv n\pmod p,\gc ...