mex (离散化+线段树)
Time Limit: 3000 ms Memory Limit: 256 MB
Description
给你一个无限长的数组,初始的时候都为0,有3种操作:
操作1是把给定区间$[l,r]$设为1,
操作2是把给定区间$[l,r]$设为0,
操作3把给定区间$[l,r]$0,1反转。
一共n个操作,每次操作后要输出最小位置的0。
Input
第一行一个整数n,表示有n个操作
接下来n行,每行3个整数op,l,r表示一个操作
Output
共n行,一行一个整数表示答案
Sample Input |
Sample Output |
|
|
HINT
对于30%的数据$1\le n\le 10^3,1\le l\le r\le 10^{18}$
对于100%的数据$1\le n\le 10^5,1\le l\le r\le 10^{18}$
题解
离散化操作区间:
首先看到$1\le l\le r\le 10^{18}$的范围,第一反应离散化。
这题的离散化是非常讲究的,我们不能只把每个区间操作的两端点提取出来离散化(我就是这么干的,其他部分都是对的,结果眼睁睁地没法输出),因为这样无法考虑到区间之间的点,如下图:
考虑到答案的位置,答案应该只可能出现在某一段操作区间右端点的右边一位,于是我们在离散一个操作区间$l,r$的同时,把$r+1$也离散化掉。操作并不涉及到$r+1$,仅仅是为了输出答案的正确和可行性。
实现修改操作:
看到熟悉的区间操作,当然要想想线段树啦。
这里采用两棵线段树的写法实现3种操作,当然也有一棵线段树搞定的写法。
两棵线段树$A,B$,都先按照离散化的规模建好,以离散化端点编号为索引。$A$记录$0$的信息,$B$记录$1$的信息。
线段树维护的信息是:$0$或$1$最左出现的位置。
第1个操作:将$A$的相应区间的信息清空(设置成最大值,因为不存在$0$了),将$B$的相应区间的信息填充(设置成区间的左端点位置),并打上清空或填充标记。日后记得下传。
第2个操作:与第1个操作完全相反。
第3个操作:将$A$的相应区间节点和$B$的相应区间节点对调。
输出:
询问$A$中的最小值位置,输出离散化前的原值即可。可以发现这个点一定是某个区间的$r$再$+1$。
时间复杂度$O(n lg n)$,空间复杂度$O(n)$。
- #include <cstdio>
- #include <algorithm>
- #define min(a,b) (a<b?a:b)
- using namespace std;
- typedef long long ll;
- const int N=1e5+;
- ll INF=;
- int n,lshtot,opt[N][],total;
- ll inp[N][],lis[N*],minloc,maxloc,orival[N*];
- void lshAndfill(){
- sort(lis+,lis++lshtot);
- total=unique(lis+,lis++lshtot)-lis-;
- for(int i=;i<=total;i++) orival[i]=lis[i];
- orival[total+]=INF;
- for(int i=;i<=n;i++){
- opt[i][]=inp[i][];
- opt[i][]=lower_bound(lis+,lis++total,inp[i][])-lis;
- opt[i][]=lower_bound(lis+,lis++total,inp[i][])-lis;
- }
- }
- struct Seg{
- int cnt,root[],sz,ch[N*][],mark[N*];
- ll info[N*];
- void build(int Size){
- sz=Size;
- _build(root[],,sz,true);
- _build(root[],,sz,false);
- }
- void _build(int &u,int l,int r,bool isfill){
- if(!u) u=++cnt;
- mark[u]=-;
- if(l==r){
- if(isfill) info[u]=l;
- else info[u]=total+;
- return;
- }
- int mid=(l+r)>>;
- _build(ch[u][],l,mid,isfill);
- _build(ch[u][],mid+,r,isfill);
- pushup(u);
- }
- inline void pushup(int u){
- info[u]=min(info[ch[u][]],info[ch[u][]]);
- }
- inline void pushdown(int u,int l,int r){
- int lc=ch[u][],rc=ch[u][];
- if(mark[u]==-) return;
- mark[lc]=mark[rc]=mark[u];
- if(mark[u]==)
- info[lc]=info[rc]=total+;
- else{
- info[lc]=l;
- info[rc]=(l+r)/+;
- }
- mark[u]=-;
- }
- void setSeg(int flag,int l,int r){
- _setSeg(root[^flag],root[^flag],,sz,l,r);
- }
- void _setSeg(int u1,int u2,int l,int r,int L,int R){
- if(L<=l&&r<=R){
- info[u1]=total+;
- info[u2]=l;
- mark[u1]=; mark[u2]=;
- return;
- }
- pushdown(u1,l,r);
- pushdown(u2,l,r);
- int mid=(l+r)>>;
- if(L<=mid) _setSeg(ch[u1][],ch[u2][],l,mid,L,R);
- if(mid<R) _setSeg(ch[u1][],ch[u2][],mid+,r,L,R);
- pushup(u1);
- pushup(u2);
- }
- void swapSeg(int l,int r){_swapSeg(root[],root[],,sz,l,r);}
- void _swapSeg(int &u1,int &u2,int l,int r,int L,int R){
- if(L<=l&&r<=R){
- swap(u1,u2);
- return;
- }
- pushdown(u1,l,r);
- pushdown(u2,l,r);
- int mid=(l+r)>>;
- if(L<=mid) _swapSeg(ch[u1][],ch[u2][],l,mid,L,R);
- if(mid<R) _swapSeg(ch[u1][],ch[u2][],mid+,r,L,R);
- pushup(u1);
- pushup(u2);
- }
- inline ll getMin(int x){return info[root[x]];}
- }seg;
- int main(){
- scanf("%d",&n);
- minloc=-;
- for(int i=;i<=n;i++){
- scanf("%lld%lld%lld",&inp[i][],&inp[i][],&inp[i][]);
- lis[++lshtot]=inp[i][];
- lis[++lshtot]=inp[i][];
- lis[++lshtot]=inp[i][]+;
- if(minloc==-) minloc=min(inp[i][],inp[i][]);
- else minloc=min(minloc,min(inp[i][],inp[i][]));
- }
- lshAndfill();
- seg.build(total);
- for(int i=;i<=n;i++){
- if(minloc>){
- printf("1\n");
- continue;
- }
- if(opt[i][]<=)
- seg.setSeg(opt[i][]==,opt[i][],opt[i][]);
- else
- seg.swapSeg(opt[i][],opt[i][]);
- printf("%lld\n",orival[seg.getMin()]);
- }
- return ;
- }
奇妙代码
mex (离散化+线段树)的更多相关文章
- 【XSY2484】mex 离散化 线段树
题目大意 给你一个无限长的数组,初始的时候都为\(0\),有3种操作: 操作\(1\)是把给定区间\([l,r]\)设为\(1\): 操作\(2\)是把给定区间\([l,r]\)设为\(0\): 操作 ...
- 南阳理工 题目9:posters(离散化+线段树)
posters 时间限制:1000 ms | 内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that ...
- SGU 180 Inversions(离散化 + 线段树求逆序对)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...
- 【POJ】2528 Mayor's posters ——离散化+线段树
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Description The citizens of Bytetown, A ...
- hpu校赛--雪人的高度(离散化线段树)
1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...
- 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树
[BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...
- 【bzoj4636】蒟蒻的数列 离散化+线段树
原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...
- 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...
- Mayor's posters (离散化线段树+对lazy的理解)
题目 题意: n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围 li,ri(1<=li<=ri<=10000000) .求出最后还能看见多少张海报. 思路: 由于 ...
- 干物妹小埋 (离散化 + 线段树 + DP)
链接:https://ac.nowcoder.com/acm/contest/992/B来源:牛客网 题目描述 在之前很火的一个动漫<干物妹小埋>中,大家对小埋打游戏喝可乐的印象十分的深刻 ...
随机推荐
- Linux exec与文件描述符
看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些.本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法. 概念:exec命令用于调用并执行指令 ...
- Hive环境搭建
hive 环境搭建需要hadoop的环境.hadoop环境的搭建不在这里赘述.参考:http://www.cnblogs.com/parkin/p/6952370.html 1.准备阶段 hive 官 ...
- mysql 出现Duplicate entry ‘xxx’ for key ‘PRIMARY’,一个自增字段达到了上限,
mysql 出现Duplicate entry 'xxx' for key 'PRIMARY',一个自增字段达到了上限,
- Hadoop-2.6.5安装
简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个分布式文 ...
- phantomjs集成到scrapy中,并禁用图片,切换UA
phantomjs是一个没有界面的浏览器,支持各种web标准,提供DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG,对于爬取一些经过js渲染的页面非常有用.但是phantomj ...
- python函数式编程之装饰器(一)
1.开放封闭原则 简单来说,就是对扩展开放,对修改封闭 在面向对象的编程方式中,经常会定义各种函数. 一个函数的使用分为定义阶段和使用阶段,一个函数定义完成以后,可能会在很多位置被调用 这意味着如果函 ...
- 造成错误“ORA-12547: TNS:lost contact”的常见原因有哪些?
造成错误“ORA-12547: TNS:lost contact”的常见原因有哪些? 真题1.造成错误“ORA-12547: TNS:lost contact”的常见原因有哪些? 答案:在执行“sql ...
- 洛谷 [P3110] 驮运
题目略带一点贪心的思想,先跑三遍最短路(边权为一,BFS比SPFA高效) 一起跑总比分开跑高效,枚举两人在何点汇合,输出最小值. #include <iostream> #include ...
- BZOJ 3879: SvT [虚树 后缀树]
传送门 题意: 多次询问,给出一些后缀,求两两之间$LCP$之和 哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊 $Suffix\ Virtual\ ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 3064 Solved: 1027[Submi ...