Loj #2585. 「APIO2018」新家

题目描述

五福街是一条笔直的道路,这条道路可以看成一个数轴,街上每个建筑物的坐标都可以用一个整数来表示。小明是一位时光旅行者,他知道在这条街上,在过去现在和未来共有 \(n\) 个商店出现。第 \(i\) 个商店可以使用四个整数 \(x_i, t_i, a_i, b_i\) 描述,它们分别表示:商店的坐标、商店的类型、商店开业的年份、商店关闭的年份。

小明希望通过时光旅行,选择一个合适的时间,住在五福街上的某个地方。他给出了一份他可能选择的列表,上面包括了 \(q\) 个询问,每个询问用二元组(坐标,时间)表示。第 \(i\) 对二元组用两个整数 \(l_i, y_i\) 描述,分别表示选择的地点 \(l_i\) 和年份 \(y_i\) 。

现在,他想计算出在这些时间和地点居住的生活质量。他定义居住的不方便指数为:在居住的年份,离居住点最远的商店类型到居住点的距离。类型 \(t\) 的商店到居住点的距离定义为:在指定的年份,类型 \(t\) 的所有营业的商店中,到居住点距离最近的一家到居住点的距离。我们说编号为 \(i\) 的商店在第 \(y\) 年在营业当且仅当 \(a_i \leq y \leq b_i\) 。注意,在某些年份中,可能在五福街上并非所有 \(k\) 种类型的商店都有至少一家在营业。在这种情况下,不方便指数定义为 −1。你的任务是帮助小明求出每对(坐标,时间)二元组居住的不方便指数。

输入格式

第一行包含三个整数 \(n\) , \(k\) 和 \(q\),分别表示商店的数量、商店类型的数量和(坐标,时间)二元组的数量。\((1\leq n,q\leq 3\times 10^5,1\leq k \leq n)\)

接下来 \(n\) 行,每行包含四个整数 \(x_i, t_i, a_i\), 和 \(b_i\) 用于描述一家商店,意义如题面所述\((1\leq x_i,a_i,b_i \leq 10^9,1\leq t_i \leq k,a_i \leq b_i)\)

接下来 \(q\) 行,每行包含两个整数 \(l_i\), 和 \(y_i\) ,表示一组(坐标,时间)查询\((1\leq l_i,y_i \leq 10^8)\)

输出格式

对于每组询问输出一个整数,包含\(q\)个整数,依次表示对于 \(q\) 组(坐标,时间)询问求出的结果。

数据范围与提示

子任务 1(5 分):\(n,q\leq 400\)

子任务 2(7 分):\(n,q\leq 6\times 10^4,k\leq 400\)

子任务 3(10 分):\(n,q\leq 3\times 10^5\),对于所有的商店\(a_i=1,b_i=10^8\)

子任务 4(23 分):\(n,q\leq 3\times 10^5\),对于所有的商店\(a_i=1\)

子任务 5(35 分):\(n,q\leq 6\times 10^4\)

子任务 6(20 分):\(n,q\leq 3\times 10^5\)

先按时间排序,然后一个房子会加入一次,删除一次。

询问的时候可以二分一个答案。假设位置是\(x\),二分的答案是\(mid\),那么如果\([l-mid,l+mid]\)之间\(k\)种商店都出现了则是一个合法情况。我们对每个商店,记录与它种类相同的前一个商店\(pre_i\)。如果坐标在\([l+mid+1,\infty]\)之间的所有商店满足\(pre_i\geq l-mid\),那么就合法,否则一定不合法。所以我们要维护区间所有商店的\(pre\)的最小值。

因为还有删除操作,所有对于线段树上每个点开一个\(multiset\)。

把坐标离散一下(其实也可以不离散),再对于每个种类加入坐标\(-\infty\)和\(\infty\)。

复杂度瓶颈\(O(Mlog^2N)\),其实可以将二分变成线段树上二分做到一个\(log\)。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 300005using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;
}int n,k,m;
struct house {int x,t,a,b;
}s[N];struct query {int x,t;
}q[N];
int T;
vector<ll>P;
int Find(ll p) {return upper_bound(P.begin(),P.end(),p)-P.begin()-1;}
const ll INF=2e9+233;
void discrete() {static vector<int>d;for(int i=1;i<=n;i++) {d.push_back(s[i].a);d.push_back(s[i].b);P.push_back(s[i].x);}for(int i=1;i<=m;i++) d.push_back(q[i].t);P.push_back(INF),P.push_back(-INF);sort(d.begin(),d.end());d.resize(unique(d.begin(),d.end())-d.begin());sort(P.begin(),P.end());P.resize(unique(P.begin(),P.end())-P.begin());T=d.size();for(int i=1;i<=n;i++) {s[i].a=lower_bound(d.begin(),d.end(),s[i].a)-d.begin()+1;s[i].b=lower_bound(d.begin(),d.end(),s[i].b)-d.begin()+1;s[i].x=lower_bound(P.begin(),P.end(),s[i].x)-P.begin();}for(int i=1;i<=m;i++) {q[i].t=lower_bound(d.begin(),d.end(),q[i].t)-d.begin()+1;}
}int rt;
int ls[N*8],rs[N*8];
int lx=1,rx=1e9;
multiset<int>::iterator it;
multiset<int>st[N*8];
int mn[N*8];
int tot;
#define mp(a,b) make_pair(a,b)
#define pr pair<int,int>
vector<pr>add[N<<2],del[N<<2];
vector<pr>que[N<<2];
int size[N],appear;
int ans[N];int New() {++tot;mn[tot]=P.size()-1;return tot;
}void update(int v) {int L=ls[v]?mn[ls[v]]:P.size()-1;int R=rs[v]?mn[rs[v]]:P.size()-1;mn[v]=min(L,R);
}void Insert(int &v,int lx,int rx,int p,int val,int flag) {if(!v) v=New();if(lx==rx) {if(flag==1) {st[v].insert(val);} else {st[v].erase(st[v].find(val));}if(st[v].size()) mn[v]=*st[v].begin();else mn[v]=P.size()-1;return ;}int mid=lx+rx>>1;if(p<=mid) Insert(ls[v],lx,mid,p,val,flag);else Insert(rs[v],mid+1,rx,p,val,flag);update(v);
}int query(int v,int lx,int rx,int l,int r) {if(!v) return P.size()-1;int ans=mn[v];if(l<=lx&&rx<=r) {return ans;}int mid=lx+rx>>1;if(r<=mid) return query(ls[v],lx,mid,l,r);else if(l>mid) return query(rs[v],mid+1,rx,l,r);else return min(query(ls[v],lx,mid,l,r),query(rs[v],mid+1,rx,l,r));
}struct node {multiset<int>pos;void Get_segment(ll l,ll r,int flag) {Insert(rt,lx,rx,r,l,flag);}void Add(int p) {if(pos.find(p)==pos.end()) {it=pos.lower_bound(p);int r=*it;int l=*(--it);Get_segment(l,r,-1);Get_segment(l,p,1);Get_segment(p,r,1);}pos.insert(p);}void Del(int p) {pos.erase(pos.find(p));if(pos.find(p)==pos.end()) {it=pos.lower_bound(p);ll r=*it;ll l=*(--it);Get_segment(l,p,-1);Get_segment(p,r,-1);Get_segment(l,r,1);}}void Init() {pos.insert(0);pos.insert(P.size()-1);Get_segment(0,P.size()-1,1);}
}coor[N];int solve(int p) {int l=0,r=1e9,mid;while(l<r) {mid=l+r>>1;int R=lower_bound(P.begin(),P.end(),p+mid+1)-P.begin();if(P[query(rt,lx,rx,R,P.size()-1)]>=p-mid) r=mid;else l=mid+1;}return l;
}int main() {n=Get(),k=Get(),m=Get();for(int i=1;i<=n;i++) {s[i].x=Get();s[i].t=Get();s[i].a=Get();s[i].b=Get();}for(int i=1;i<=m;i++) {q[i].x=Get(),q[i].t=Get();}discrete();lx=0,rx=P.size()-1;for(int i=1;i<=n;i++) {add[s[i].a].push_back(mp(s[i].x,s[i].t));del[s[i].b].push_back(mp(s[i].x,s[i].t));}for(int i=1;i<=m;i++) {que[q[i].t].push_back(mp(q[i].x,i));}for(int i=1;i<=k;i++) coor[i].Init();for(int i=1;i<=T;i++) {for(int j=0;j<add[i].size();j++) {size[add[i][j].second]++;if(size[add[i][j].second]==1) appear++;coor[add[i][j].second].Add(add[i][j].first);}if(appear<k) {for(int j=0;j<que[i].size();j++) {ans[que[i][j].second]=-1;}} else {for(int j=0;j<que[i].size();j++) {ans[que[i][j].second]=solve(que[i][j].first);}}for(int j=0;j<del[i].size();j++) {size[del[i][j].second]--;if(size[del[i][j].second]==0) appear--;coor[del[i][j].second].Del(del[i][j].first);}}for(int i=1;i<=m;i++) {cout<<ans[i]<<"\n";}return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/11025517.html

Loj #2585. 「APIO2018」新家相关推荐

  1. Loj #3055. 「HNOI2019」JOJO

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

  2. Loj #2568. 「APIO2016」烟花表演

    Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...

  3. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  4. LOJ#2230. 「BJOI2014」大融合

    LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...

  5. loj#2143. 「SHOI2017」组合数问题

    loj#2143. 「SHOI2017」组合数问题 题目描述 Solution 考虑转化一下我们要求的东西. ∑i=0n(nkik+r)=∑i=0n(nki)[i≡r(modk)]\sum_{i=0} ...

  6. LOJ#2542. 「PKUWC2018」随机游走

    LOJ#2542. 「PKUWC2018」随机游走 题目描述 Solution 去过一个点集中所有节点的期望时间不好求,考虑min−maxmin-maxmin−max容斥,转化为求第一次到达某一个点集 ...

  7. LOJ#2145. 「SHOI2017」分手是祝愿

    LOJ#2145. 「SHOI2017」分手是祝愿 题目描述 Solution 首先有一个结论: 灯的状态序列a1,a2...ana_1,a_2...a_na1​,a2​...an​唯一对应了一个最优 ...

  8. Loj #2983. 「WC2019」数树

    Loj #2983. 「WC2019」数树 题目背景 白兔喜欢树. 白云喜欢数数. 有 \(n\) 只鼠,白兔用 \(n − 1\) 根蓝色绳子把它们连成了一棵树,每根蓝色绳子连着两只鼠,白云用 \( ...

  9. Loj #2554. 「CTSC2018」青蕈领主

    Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...

最新文章

  1. HashMap为何从头插入改为尾插入
  2. 使用proc文件系统
  3. 潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)
  4. 编辑器eslint格式_vscode保存代码,自动按照eslint规范格式化代码设置
  5. Mendeley从已有文献找相关文献的方法
  6. 华为hcip认证考试题库有哪些内容?华为hcip认证考试题库试题举例
  7. 交换机芯片笔记1.1
  8. 蓝桥杯 省赛 杨辉三角形 python组(转)
  9. RoboWare Studio安装教程
  10. 1076 Wifi密码
  11. opencv 训练样本
  12. 2022年1月份报告合集(共222份)
  13. 画色彩如何画出体积感
  14. 设置漂亮的eclipse主题(Theme)风格
  15. format code appears twice
  16. 辩证唯物论和唯物辩证法区别
  17. word破解文档保护
  18. 门户级UGC系统的技术进化路线——新浪新闻评论系统的架构演进和经验总结
  19. 怎么确保问卷数据的有效性和安全性?
  20. sai实现空心文字的教程

热门文章

  1. 网站登录密码忘记后,通过向手机发送验证码实现找回密码的实现方法
  2. QT小项目------>记事本
  3. 亚微米SOI脊型波导(课堂笔记)
  4. Taro(React)实现具有滚动效果的倒数计时器
  5. Eslint semi 结尾分号设置与否
  6. GitOps与ChatOps的落地实践
  7. 华为机试—拼音翻译成阿拉伯数字(有Wan,Qian,Bai,Shi单位)
  8. 苹果手机怎么投屏?图文教程,轻松学会
  9. keydown与keypress的区别,组合键
  10. 国庆中秋除了发月饼,企业更应该做什么?