题面在这里

description

在一个数轴上:

给定\(n\)个商店,每个商店有一个开业时间,关门时间,坐标和销售物品的种类

同时有\(m\)个询问,每个询问给你一个时间\(t[i]\)和地点\(d[i]\)试求在\(t[i]\)时刻,一个住在\(d[i]\)的人,为了买某种商品最远需要跑多长距离。

data range

\[n,m\le 3\times 10^5,数轴长度\le 10^9
\]

solution

\(Luogu\)评测机好评,我这种大力\(Splay\)都跑得过

把每一家商店存在的区间看成一组在数轴上的插入,删除操作,使用\(Splay\)记录每家商店前一家该种类型商店的位置\(pre\),用\(set\)记一下就可以了

询问的时候二分距离\(len\)问题即检查是否有一种商店不在\([d[i]-len,d[i]+len]\)内,

即求\(min_{(d[i]+len,\infty)}pre\),于是记录一个最小值就可以了

艰苦战斗

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
//#define TEST
#define FILE ""
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=1000010;
const int inf=1e9+7;
const dd pi=acos(-1);
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
freopen(FILE"102","r",stdin);
freopen(FILE"a.out","w",stdout);
} int n,k,q,m,ans[N];
int x[N],t[N],a[N],b[N],l[N],y[N];
struct operators{
int opt;//0表示插入一个商店,1表示询问,2表示删除一个商店
int pos,tim,kind;
}Q[N];
bool cmp(operators a,operators b){
if(a.tim==b.tim)return a.opt<b.opt;
else return a.tim<b.tim;
} il void init(){
n=read();k=read();q=read();
for(RG int i=1;i<=n;i++){
x[i]=read();t[i]=read();a[i]=read();b[i]=read();
Q[++m]=(operators){0,x[i],a[i],t[i]};
Q[++m]=(operators){2,x[i],b[i],t[i]};
}
for(RG int i=1;i<=q;i++){
l[i]=read();y[i]=read();
Q[++m]=(operators){1,l[i],y[i],i};
}
sort(Q+1,Q+m+1,cmp);
} struct store{int pos,id;};
bool operator <(store a,store b){return a.pos<b.pos;}
multiset<store>S[N];
multiset<store>::iterator tmp; int tot,rt;
int fa[N],s[2][N],pre[N],minpre[N],pos[N];
#define isr(i) (s[1][fa[i]]==i)
il void update(RG int i){
minpre[i]=pre[i];
if(pre[s[0][i]]&&pos[minpre[i]]>pos[minpre[s[0][i]]])
minpre[i]=minpre[s[0][i]];
if(pre[s[1][i]]&&pos[minpre[i]]>pos[minpre[s[1][i]]])
minpre[i]=minpre[s[1][i]];
}
il void rot(RG int i){
RG int j=fa[i],k=fa[j];
RG bool b=isr(i);
if(k)s[isr(j)][k]=i;fa[i]=k;
if(s[!b][i])fa[s[!b][i]]=j;s[b][j]=s[!b][i];
fa[j]=i;s[!b][i]=j;
update(j);
}
il void splay(int i,int a){
for(RG int j=fa[i];j!=a;rot(i),j=fa[i])
if(fa[j]!=a)isr(i)^isr(j)?rot(i):rot(j);
if(!a)rt=i;update(i);
} il void insert(int p){
RG int i=rt,ff=0;
while(i){ff=i;i=s[p>pos[i]][i];}
if(!i)i=++tot;if(!ff)rt=i;
else s[p>pos[ff]][ff]=i;
if(ff)fa[i]=ff;pos[i]=p;
splay(i,0);
} il void find(int p){
RG int i=rt;
while(s[p>pos[i]][i])
i=s[p>pos[i]][i];
splay(i,0);
} il int Nxt(int p,bool b){
find(p);RG int i=rt;
if(pos[i]>p&&b)return rt;
if(pos[i]<p&&!b)return rt;
i=s[b][rt];while(s[!b][i])i=s[!b][i];return i;
} il void Delete(int i){
splay(i,0);
RG int nxt=s[0][i],lst=s[1][i];
while(s[1][nxt])nxt=s[1][nxt];
while(s[0][lst])lst=s[0][lst]; splay(nxt,0);splay(lst,nxt);
fa[i]=s[0][lst]=0;
update(lst);update(nxt);
} il int query(int l){
RG int L=Nxt(l,0);splay(L,0);
return pos[minpre[s[1][L]]];
} il void Ins(int pos,int kind){
insert(pos);splay(tot,0);
tmp=S[kind].upper_bound((store){pos,0});
minpre[tot]=pre[tot]=pre[tmp->id];
minpre[tmp->id]=pre[tmp->id]=tot;
splay(tot,0);splay(tmp->id,0);
S[kind].insert((store){pos,tot});
}
il void Del(int pos,int kind){
tmp=S[kind].upper_bound((store){pos,0});
pre[tmp->id]=pre[pre[tmp->id]];splay(tmp->id,0);
tmp--;Delete(tmp->id);
S[kind].erase(tmp);
}
il int Qry(int pos){
RG int l=0,r=100000000,mid,ret=-1;
while(l<=r){
mid=(l+r)>>1;
if(query(pos+mid+1)>=pos-mid)
ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
} int main()
{
init();pos[0]=-inf;
for(RG int i=1;i<=k;i++){
insert(-inf);update(tot);S[i].insert((store){-inf,tot});
insert(inf);S[i].insert((store){inf,tot});
minpre[tot]=pre[tot]=tot-1;update(tot);
}
for(RG int i=1;i<=m;i++){
if(Q[i].opt==0)Ins(Q[i].pos,Q[i].kind);
if(Q[i].opt==1)ans[Q[i].kind]=Qry(Q[i].pos);
if(Q[i].opt==2)Del(Q[i].pos,Q[i].kind);
}
for(RG int i=1;i<=q;i++)printf("%d\n",ans[i]);
return 0;
}

[APIO2018] New Home的更多相关文章

  1. 【APIO2018】铁人两项

    [APIO2018]铁人两项 题目描述 大意就是给定一张无向图,询问三元组\((s,c,f)\)中满足\(s\neq c\neq f\)且存在\((s\to c\to f)\)的简单路径(每个点最多经 ...

  2. 【APIO2018】铁人两项(圆方树,动态规划)

    [APIO2018]铁人两项(圆方树,动态规划) 题面 UOJ 洛谷 BZOJ 题解 嘤嘤嘤,APIO的时候把一个组合数写成阶乘了,然后这题的70多分没拿到 首先一棵树是很容易做的,随意指定起点终点就 ...

  3. 【APIO2018】新家(线段树)

    [APIO2018]新家(线段树) 题面 UOJ 洛谷 BZOJ 题解 论比赛时想不到二分的危害,就只能Cu滚粗 既然不要在线,那么考虑离线做法. 既然时间是区间,那么显然按照时间顺序处理答案. 显然 ...

  4. CTSC/APIO2018滚粗记

    CTSC/APIO2018滚粗记 前言 从\(5.5\)晚上的火车到\(5.14\)早上的高铁 \(10\)天的时间真的过去的很快. 眨眼间,就到了今天晚上的颁奖. 至于结果如何,反而并不是那么重要了 ...

  5. CTSC2018&APIO2018游记

    CTSC2018&APIO2018游记 Day 0 傍晚出发,从长沙通往帝都的软卧哟. 然而长沙某中学坐高铁比我们晚出发还早到 Day 1 为了正经地写游记我决定忍住不在博客里吐槽酒店. 午饭 ...

  6. APIO2018酱油记

    苟比主席树太难了学不会 还是把APIO几天的过程记下来吧...免得忘了 DAY -5 去CTSC的人都走了,机房好冷清...只有我.PSB.yasar.Chlience四个人 CSTC辣么难又辣么贵, ...

  7. [APIO2018] Duathlon 铁人两项 圆方树,DP

    [APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...

  8. 【LG4631】[APIO2018]Circle selection 选圆圈

    [LG4631][APIO2018]Circle selection 选圆圈 题面 洛谷 题解 用\(kdt\)乱搞剪枝. 维护每个圆在\(x.y\)轴的坐标范围 相当于维护一个矩形的坐标范围为\([ ...

  9. LOJ #2585. 「APIO2018」新家

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

  10. 「APIO2018新家」

    「APIO2018新家」 题目描述 五福街是一条笔直的道路,这条道路可以看成一个数轴,街上每个建筑物的坐标都可以用一个整数来表示.小明是一位时光旅行者,他知道在这条街上,在过去现在和未来共有 \(n\ ...

随机推荐

  1. python的字典数据类型及常用操作

    字典的定义与特性 字典是Python语言中唯一的映射类型. 定义:{key1: value1, key2: value2} 1.键与值用冒号“:”分开: 2.项与项用逗号“,”分开: 特性: 1.ke ...

  2. MySQL Waiting for table metadata lock的解决方法

    最近需要在某一个表中新增字段,使用Sequel Pro 或者Navicat工具都会出现程序没有反应,使用 show processlist 查看,满屏都是 Waiting for table meta ...

  3. pygame小游戏之坦克大战

    以前在学校的时候无聊的学了会pygame.看了大概一周的教学视频,做出来个坦克大战的小游戏 Python3.5  pycharm import pygame,sys,time from random ...

  4. python中一些内置函数实例

    lambda表达式 简单函数可用lambda表达式 1. def f1() return(123) r1=f1() print() 2. f2=lambda:123 r2=f2() print() 以 ...

  5. Linux 控制台

    shell shell命令分为两种:分别是内部命令和外部命令. 内部命令:在安装的时候嵌入系统内核. 外部命令:以文件的形式存在. 可以使用type命令查看是内部命令还是外部命令. Linux中,默认 ...

  6. HyperLedger Fabric 1.4 超级账本简介(5.2)

    超级账本(Hyperledger)是推动区块链跨行业应用的开源项目的总称,组织成员可以发起新的区块链项目,加入到超级账本项目(Hyperledger)中,但需要遵循Hyperledger的生命周期.  ...

  7. Hive 函数之内置运算符

    本章介绍Hive的内置运算符.在Hive有四种类型的运算符: 关系运算符 算术运算符 逻辑运算符 复杂运算符 关系运算符 这些操作符被用来比较两个操作数.下表描述了在Hive中可用的关系运算符: 运算 ...

  8. CentOS 7 systemd添加自定义系统服务

    systemd: CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,即:/usr/lib/systemd/syste ...

  9. 区分Oracle的数据库,实例,服务名,SID

    文章摘自:http://www.zhetao.com/content240 感谢分享O(∩_∩)O~ 在实际的开发应用中,关于Oracle数据库,经常听见有人说建立一个数据库,建立一个Instance ...

  10. leetcode笔记--2 reverse string

    my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...