题解

成功把自己写自闭了

离散化之后再二分我是真不会算坐标啊我这个zz

先离散化所有坐标,然后对于每个位置维护一个最小前驱,然后线段树区间维护最小前驱

什么?位置一样?那就给每个大小为1的位置开个multiset,往上维护的时候就直接左右区间取min

然后就是,在线段树上二分了

我们把正无穷和负无穷位置加进去会比较好维护

如果\((x - m,x + m)\)这个区间不合法,转化为\([x + m,+\infty)\)有前驱在\((-\infty,x - m]\)内

也就意味着我们的距离大小至少是m

在线段树上二分呢,我们找的是这个\(x + m\)在的区间,显然x在右区间就往右区间走

如果x在左区间,那么看看\(mid + 1\)所在的点算出的\(m = pos[mid + 1] - x\)是否满足最小前缀\(mn <= x - m\)

如果满足这个\(x + m\)肯定在右区间

不满足就在左区间

然而,当你二分到一个点的时候,事实上,这个\(x + m\)是可能落在两个坐标中间的,也就是当前节点和当前节点+1,分别计算输出即可

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 300005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,K,Q;
struct qry_node {
int y,x,t;
friend bool operator < (const qry_node &a,const qry_node &b) {
if(a.y != b.y) return a.y < b.y;
else if(a.t != b.t) return a.t > b.t;
return a.x < b.x;
}
}qry[MAXN * 4];
int qt;
int pos[MAXN],tot,ans[MAXN],cnt[MAXN],hs;
struct node {
int l,r,mq;
}tr[MAXN * 4];
multiset<int> S[MAXN];
multiset<int> T[MAXN * 4];
void update(int u) {
tr[u].mq = min(tr[u << 1].mq,tr[u << 1 | 1].mq);
}
void build(int u,int l,int r) {
tr[u].l = l;tr[u].r = r;
if(l == r) {
tr[u].mq = tot + 1;
if(l == tot) {
tr[u].mq = 1;
for(int i = 1 ; i <= K ; ++i) T[u].insert(1);
}
return;
}
int mid = (l + r) >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
update(u);
}
void Change(int u,int pos,int v) {
if(tr[u].l == tr[u].r) {
if(v > 0) T[u].insert(v);
else T[u].erase(T[u].find(-v));
if(T[u].size() >= 1) tr[u].mq = *T[u].begin();
else tr[u].mq = tot + 1;
return;
}
int mid = (tr[u].l + tr[u].r) >> 1;
if(pos <= mid) Change(u << 1,pos,v);
else Change(u << 1 | 1,pos,v);
update(u);
}
void Query(int u,int x,int suf,int &a) {
if(tr[u].l == tr[u].r) {
int t = min(tr[u].mq,suf);
a = max(a,min(x - pos[t],pos[tr[u].l] - x));
if(tr[u].l < tot) a = max(a,min(x - pos[suf],pos[tr[u].l + 1] - x));
return;
}
int mid = (tr[u].l + tr[u].r) >> 1;
if(x > pos[mid]) {return Query(u << 1 | 1,x,suf,a);}
else {
int t = min(tr[u << 1 | 1].mq,suf);
if(pos[t] > 2 * x - pos[mid + 1]) {
return Query(u << 1,x,min(suf,tr[u << 1 | 1].mq),a);
}
else if(pos[t] <= 2 * x - pos[mid + 1]) {return Query(u << 1 | 1,x,suf,a);}
}
}
void Init() {
read(N);read(K);read(Q);
int x,t,a,b;
for(int i = 1 ; i <= N ; ++i) {
read(x);read(t);read(a);read(b);
qry[++qt] = (qry_node){a,x,t};
qry[++qt] = (qry_node){b + 1,x,-t};
pos[++tot] = x;
}
int l,y;
for(int i = 1 ; i <= Q ; ++i) {
read(l);read(y);
qry[++qt] = (qry_node){y,l,- i - K};
//pos[++tot] = l;
}
pos[++tot] = -1e9;pos[++tot] = 2e9;
sort(qry + 1,qry + qt + 1);
sort(pos + 1,pos + tot + 1);
tot = unique(pos + 1,pos + tot + 1) - pos - 1;
build(1,1,tot);
}
void Solve() {
for(int i = 1 ; i <= K ; ++i) {
S[i].insert(1),S[i].insert(tot);
}
for(int i = 1 ; i <= qt ; ++i) {
int u = qry[i].t; if(u >= -K) {
int x = lower_bound(pos + 1,pos + tot + 1,qry[i].x) - pos;
if(u > 0) {
S[u].insert(x);
auto k = S[u].find(x);
auto g = k,h = k;++g,--h;
if(*g != *k) {
Change(1,*g,*k);Change(1,*g,-(*h));
Change(1,*k,*h);
}
if(cnt[u] == 0 && cnt[u] + 1 == 1) ++hs;
++cnt[u];
}
else {
u = -u;
auto k = S[u].find(x);
auto g = k,h = k;++g,--h;
if(*g != *k) {
Change(1,*g,-(*k));Change(1,*g,*h);
Change(1,*k,-(*h));
}
S[u].erase(k);
if(cnt[u] == 1 && cnt[u] - 1 == 0) --hs;
--cnt[u];
}
}
else {
if(hs != K) ans[- K - u] = -1;
else Query(1,qry[i].x,tot + 1,ans[-K - u]);
}
}
for(int i = 1 ; i <= Q ; ++i) {
out(ans[i]);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}

【LOJ】#2585. 「APIO2018」新家的更多相关文章

  1. LOJ #2585. 「APIO2018」新家

    #2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...

  2. LOJ 2585 「APIO2018」新家 ——线段树分治+二分答案

    题目:https://loj.ac/problem/2585 算答案的时候要二分! 这样的话,就是对于询问位置 x ,二分出一个最小的 mid 使得 [ x-mid , x+mid ] 里包含所有种类 ...

  3. LOJ #2587「APIO2018」铁人两项

    是不是$ vector$存图非常慢啊...... 题意:求数对$(x,y,z)$的数量使得存在一条$x$到$z$的路径上经过$y$,要求$x,y,z$两两不同  LOJ #2587 $ Solutio ...

  4. LOJ 2586 「APIO2018」选圆圈——KD树

    题目:https://loj.ac/problem/2586 只会 19 分的暴力. y 都相等,仍然按直径从大到小做.如果当前圆没有被删除,那么用线段树把 [ x-r , x+r ] 都打上它的标记 ...

  5. LOJ 2587 「APIO2018」铁人两项——圆方树

    题目:https://loj.ac/problem/2587 先写了 47 分暴力. 对于 n<=50 的部分, n3 枚举三个点,把图的圆方树建出来,合法条件是 c 是 s -> f 路 ...

  6. 【刷题】LOJ 2587 「APIO2018」铁人两项

    题目描述 比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成. 最近,比特镇获得了一场铁人两项锦标赛的主办权.这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行车完成第二段 ...

  7. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  8. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  9. Loj #2719. 「NOI2018」冒泡排序

    Loj #2719. 「NOI2018」冒泡排序 题目描述 最近,小 S 对冒泡排序产生了浓厚的兴趣.为了问题简单,小 S 只研究对 *\(1\) 到 \(n\) 的排列*的冒泡排序. 下面是对冒泡排 ...

随机推荐

  1. 洛谷P3380 【模板】二逼平衡树(树套树,树状数组,线段树)

    洛谷题目传送门 emm...题目名写了个平衡树,但是这道题的理论复杂度最优解应该还是树状数组套值域线段树吧. 就像dynamic ranking那样(蒟蒻的Sol,放一个link骗访问量233) 所有 ...

  2. CentOS服务器配置SSH免密码登录

    由于工作需要,经常要登录到多台服务器远程操作,每次都是ssh user@host:port 再输入密码,时间长了,难免觉得乏味-- 故而从度娘那里扒来了一些让SSH免密码登录的办法,其实这也是使用Gi ...

  3. Json对象与Json字符串

  4. ElasticStack系列之十七 & 大文本搜索性能提升方案

    1. 什么是大文本?具体是什么? 首先需要理解,ElasticSearch 建立索引完成全文检索的前提是将待检索的信息导入到 ElasticSearch 中.而有的信息对应的正文内容会非常的打,可能达 ...

  5. node.js浅谈

    相信大家对node.js也很不陌生吧,现在我来总结一下常用的吧~ 我们Web全栈工程师最多的就是用Node作为后台了,Node.js虽然可以作为后台语言,但是相对于Java那些老牌后台语言真是一点优势 ...

  6. Tomcat权威指南-读书摘要系列10

    Tomcat集群 一些集群技术 DNS请求分配 TCP网络地址转换请求分配 Mod_proxy_balance负载均衡与故障复原 JDBC请求分布与故障复原

  7. Java基础-二进制以及字符编码简介

    Java基础-二进制以及字符编码简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必计算机毕业的小伙伴或是从事IT的技术人员都知道数据存储都是以二进制的数字存储到硬盘的.从事开 ...

  8. Shell中的case命令

    case语句和判断语句[if...elif...else]功能类似;当在逻辑判断比较简单的情况下,比后者的代码量要少许多.case用法,用变量来匹配某值,如果匹配成功则执行它下面的命令,直到 ::为止 ...

  9. python3中__get__,__getattr__,__getattribute__的区别

    __get__,__getattr__和__getattribute都是访问属性的方法,但不太相同. object.__getattr__(self, name) 当一般位置找不到attribute的 ...

  10. [转]CSS浏览器兼容问题总结

    E6.0,ie7.0与Firefox的CSS兼容性问题1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-left, margin-right 为 auto 时已经居中,  ...