[bzoj5462]新家
先离线,将询问按照时间排序,维护商店出现和消失
对于每一个询问,先二分枚举答案,假设是ans,
即要求对于区间[l-ans,l+ans],商店的种类数是k(l是询问的位置)
(当然需要先将所有位置离散一下,l-ans和l+ans找到等价的位置)
那个条件并不是很好处理,但可以转化成另一个条件:
l+ans以后的每一个商店的前驱(上一个同类型商店)都不在l-ans之前
,只需要快速求前驱和前驱的最小值就可以了,可以套数据结构
具体来说,就是维护一个线段树和一个set,分别表示:
1.商店前驱的线段树(离散,维护区间min);2.每一种类型的set(查找前驱)
(但因为这个前驱需要支持删除,线段树的叶子节点还要开一个set)
这样的复杂度是o(nlog^2n),但可以直接在线段树上二分:
线段树上二分的是l+ans(二分出来的结果再减掉ans就行了),设
答案是k,答案合法当且仅当k+k的后缀最小值<=2l(l是询问位置)
,而后缀最小值可以在递归下来的时候不断维护,因此可行
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 300005
4 #define mid (l+r>>1)
5 #define oo 0x3f3f3f3f
6 struct ji{
7 int x,k,t,p;
8 bool operator < (const ji &a)const{
9 return (t<a.t)||(t==a.t)&&(p>a.p);
10 }
11 }a[N*3];
12 map<int,int>mat;
13 multiset<int>s1[N],s2[N];
14 multiset<int>::iterator it1,it2;
15 int V,VV,n,m,k,q,r,ans[N],f[N*30],ls[N*30],rs[N*30];
16 void read(){
17 for(int i=1;i<=n;i++){
18 m++;
19 scanf("%d%d%d",&a[m].x,&a[m].k,&a[m].t);
20 a[m++].p=1;
21 a[m]=a[m-1];
22 scanf("%d",&a[m].t);
23 a[m].p=-1;
24 }
25 for(int i=1;i<=q;i++){
26 m++;
27 scanf("%d%d",&a[m].x,&a[m].t);
28 a[m].k=i;
29 }
30 sort(a+1,a+m+1);
31 }
32 void update(int &k,int l,int r,int x,int y,int z){
33 if (!k)k=++V;
34 if (l==r){
35 if (!mat[l])mat[l]=++VV;
36 l=mat[l];
37 if (y)s2[l].insert(y);
38 if (z)s2[l].erase(s2[l].lower_bound(z));
39 if (!s2[l].size())f[k]=oo;
40 else f[k]=*s2[l].begin();
41 return;
42 }
43 if (x<=mid)update(ls[k],l,mid,x,y,z);
44 else update(rs[k],mid+1,r,x,y,z);
45 f[k]=min(f[ls[k]],f[rs[k]]);
46 }
47 int query(int k,int l,int r,int x,int y){
48 if (l==r)
49 if (l==oo)return -1;
50 else return l-x;
51 if ((mid<x)||(mid+min(y,f[rs[k]])<2*x))return query(rs[k],mid+1,r,x,y);
52 return query(ls[k],l,mid,x,min(y,f[rs[k]]));
53 }
54 void add(int x,int k){
55 it1=s1[k].upper_bound(x);
56 it2=it1--;
57 update(r,1,oo,x,*it1,0);
58 update(r,1,oo,*it2,x,*it1);
59 s1[k].insert(x);
60 }
61 void del(int x,int k){
62 s1[k].erase(s1[k].lower_bound(x));
63 it1=s1[k].upper_bound(x);
64 it2=it1--;
65 update(r,1,oo,x,0,*it1);
66 update(r,1,oo,*it2,*it1,x);
67 }
68 int main(){
69 scanf("%d%d%d",&n,&k,&q);
70 read();
71 f[0]=oo;
72 for(int i=1;i<=k;i++){
73 s1[i].insert(-oo);
74 s1[i].insert(oo);
75 update(r,1,oo,oo,-oo,0);
76 }
77 for(int i=1;i<=m;i++){
78 if (a[i].p>0)add(a[i].x,a[i].k);
79 if (a[i].p<0)del(a[i].x,a[i].k);
80 if (!a[i].p)ans[a[i].k]=query(r,1,oo,a[i].x,oo);
81 }
82 for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
83 }
[bzoj5462]新家的更多相关文章
- 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
- BZOJ 3631 【JLOI2014】 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1231 Solved: 620[Submit][Stat ...
- 【bzoj3631】[JLOI2014]松鼠的新家
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松 ...
- 【BZOJ3631】松树的新家 树链剖分
BZOJ3631 松树的新家 Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- [JLOI2014] 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
随机推荐
- python单例模式设计
class MyTest(): my_obj = None def __new__(cls,*args,**kwargs): if not cls.my_obj: cls.my_obj =object ...
- python中对列表的排序
1.sort()对列表永久性的排序,首字母按照字母表的顺序排列 book=['python','java','c++','web'] book.sort() print(book) 结果如下: 2.向 ...
- 【UE4 设计模式】策略模式 Strategy Pattern
概述 描述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法的变化不会影响到使用算法的客户. 套路 Context(环境类) 负责使用算法策略,其中维持了一 ...
- [no code][scrum meeting] Alpha 11
项目 内容 会议时间 2020-04-17 会议主题 OCR紧急技术风险分析 会议时长 30min 参会人员 PM+OCR组成员 $( "#cnblogs_post_body" ) ...
- python的random模块生成随机数
python的random函数 random.random() 生成0-1之间的随机数 random.uniform(a,b)生成a,b之间的浮点数 random.randint(a,b)生成a,b之 ...
- PriorityQueue(优先队列)
PriorityQueue 翻译过来就是优先队列,本质是一个堆, 默认情况下堆顶每次都保留最小值,每插入一个元素,仍动态维护堆顶为最小值. PriorityQueue 一个基于优先级的无界优先级队列. ...
- js计算精确度丢失问题解决
(function () { var calc = { /* 函数,加法函数,用来得到精确的加法结果 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精 ...
- popStar机机对战数据生成器代码(C#)
代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...
- 手把手教你学Dapr - 4. 服务调用
上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...
- openstack 后期维护(四)--- 删除僵尸卷
前言: 在长时间使用openstack之后,删除虚机后,经常会有因这样那样的问题,导致卷处于僵尸状态,无法删除! 状态一: 虚机已近删除,然而卷却挂在到了 None上无法删除 解决办法: 1.# ci ...