Description

给你一个无限长的数组,初始的时候都为0,有3种操作:

操作1是把给定区间[l,r][l,r] 设为1,

操作2是把给定区间[l,r][l,r] 设为0,

操作3把给定区间[l,r][l,r] 0,1反转。

一共n个操作,每次操作后要输出最小位置的0。

Input

第一行一个整数n,表示有n个操作

接下来n行,每行3个整数op,l,r表示一个操作

Output

共n行,一行一个整数表示答案

Sample Input

3
1 3 4
3 1 6
2 1 3

Sample Output

1
3
1

HINT

对于30%的数据\(1≤n≤10^3,1≤l≤r≤10^{18}1≤n≤10^3,1≤l≤r≤10^{18}\)

对于100%的数据\(1≤n≤10^5,1≤l≤r≤10^{18}1≤n≤10^5,1≤l≤r≤10^{18}\)

Solution

正解时空复杂度为\(O(n \log n)\).

我的解法时空复杂度也是\(O(n \log n)\)

但是它就是MLE了那么一点.

正解: 离散化 + 线段树.

我的做法: 开两棵离散线段树, 分别代表0和1, 每次把一棵中的一些点拆下来放到另一棵里面.

/*
mind the value of INF
*/ #include <cstdio>
#include <cctype> namespace Zeonfai
{
inline long long getInt()
{
long long a = 0, sgn = 1; char c;
while(! isdigit(c = getchar())) if(c == '-') sgn *= -1;
while(isdigit(c)) a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
}
const long long INF = (long long)1e18 + 7;
// const long long INF = 11;
struct segmentTree
{
struct node
{
node *suc[2];
long long L, R;
long long vst, sz;
inline node(long long _L, long long _R)
{
L = _L; R = _R; vst = 0; sz = R - L + 1;
for(long long i = 0; i < 2; ++ i) suc[i] = NULL;
}
}*rt;
struct result
{
node *a, *b;
inline result(node *_a, node *_b) {a = _a; b = _b;}
};
inline void initialize() {rt = new node(1, INF);}
result split(node *u, long long L, long long R)
{
if(u == NULL || (u->L >= L && u->R <= R)) return result(u, NULL);
long long mid = u->L + u->R >> 1;
if(! u->vst)
{
u->suc[0] = new node(u->L, mid); u->suc[1] = new node(mid + 1, u->R);
u->vst = 1;
}
node *_u = new node(u->L, u->R); _u->vst = 1;
if(L <= mid)
{
result res = split(u->suc[0], L, R);
_u->suc[0] = res.a; u->suc[0] = res.b;
}
if(R > mid)
{
result res = split(u->suc[1], L, R);
_u->suc[1] = res.a; u->suc[1] = res.b;
}
u->sz = 0;
for(long long i = 0; i < 2; ++ i) if(u->suc[i] != NULL) u->sz += u->suc[i]->sz;
_u->sz = 0;
for(long long i = 0; i < 2; ++ i) if(_u->suc[i] != NULL) _u->sz += _u->suc[i]->sz;
return result(_u, u);
}
inline node* split(long long L, long long R)
{
result res = split(rt, L, R);
rt = res.b; return res.a;
}
inline node* merge(node *u, node *_u)
{
if(u == NULL) return _u; if(_u == NULL) return u;
for(long long i = 0; i < 2; ++ i) u->suc[i] = merge(u->suc[i], _u->suc[i]);
u->sz = 0;
for(long long i = 0; i < 2; ++ i) if(u->suc[i] != NULL) u->sz += u->suc[i]->sz;
delete _u; return u;
}
inline void merge(node *u) {rt = merge(rt, u);}
long long query(node *u)
{
if(! u->vst) return u->L;
else if(u->suc[0] != NULL && u->suc[0]->sz) return query(u->suc[0]);
else return query(u->suc[1]);
}
inline long long query() {return query(rt);}
}seg[2];
int main()
{ #ifndef ONLINE_JUDGE freopen("mex.in", "r", stdin);
freopen("mex.out", "w", stdout); #endif using namespace Zeonfai;
seg[0].initialize();
long long n = getInt();
for(long long i = 0; i < n; ++ i)
{
long long opt = getInt(); long long L = getInt(), R = getInt();
if(opt == 1) seg[1].merge(seg[0].split(L, R));
else if(opt == 2) seg[0].merge(seg[1].split(L, R));
else if(opt == 3)
{
segmentTree::node *u = seg[0].split(L, R), *v = seg[1].split(L, R);
seg[0].merge(v); seg[1].merge(u);
}
printf("%lld\n", seg[0].query());
}
}

noip2017集训测试赛(三) Problem B: mex [补档]的更多相关文章

  1. noip2017集训测试赛(三)Problem C: MST

    题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...

  2. noip2017集训测试赛(十一)Problem C: 循环移位

    题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 ...

  3. noip2017集训测试赛(六)Problem A: 炮艇大赛之正式赛

    题目描述 给定一个长度为\(L \le 10^9\)的环形赛道, \(n \le 10^5\)个人在上面赛艇. 每个人的速度都不相同, 假如为正则顺时针走, 否则逆时针走. 当两个人相遇时, 他们就会 ...

  4. noip2017集训测试赛(四)Problem A: fibonacci

    题目大意 给你一个序列\(a_1, a_2, ..., a_n\). 我们令函数\(f(n)\)表示斐波那契数列第\(n\)项的值. 总共\(m\)个操作, 分为以下两种: 将\(x \in [L, ...

  5. noip2019集训测试赛(二十一)Problem B: 红蓝树

    noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君 ...

  6. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  7. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  8. noip2019集训测试赛(二十一)Problem A: Colorful Balls

    Problem A: Colorful Balls Description Snuke放了N个一排彩色的球.从左起第i个球的颜色是ci重量是wi她可以通过执行两种操作对这些球重新排序操作1:选择两个相 ...

  9. 2016集训测试赛(二十六)Problem A: bar

    Solution 首先审清题意, 这里要求的是子串而不是子序列... 我们考虑用1表示p, -1表示j. 用sum[i]表示字符串前\(i\)的前缀和. 则我们考虑一个字符串\([L, R]\)有什么 ...

随机推荐

  1. 7月21号day13总结

    今天学习过程和小结 学习了hive中的数据类型以及hive的简单查询, 学习了sqoop version用sqoop导入导出数据. 主要用于在Hadoop(Hive)与传统的数据库(mysql.pos ...

  2. ntpq –p命令

    ntpq用来监视ntpd操作,ntpq -p查询网络中的NTP服务器,同时显示客户端和每个服务器的关系 [root@ ~]# ntpq -p remote refid st t when poll r ...

  3. linux下解压,压缩命令大全---方便新手查看

    本文最后讲述如何在打包时排除某些文件 .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) --- ...

  4. 【比赛】百度之星2017 初赛Round B

    第一题 题意:给定n*m网络,定义两个棋子在同行同列则相互攻击,同时要求两个棋子的行和列不能一小一大,求满足条件的最大摆放的方案数. 题解:ans=C(max(n,m),min(n,m)),就是在ma ...

  5. [ CodeVS冲杯之路 ] P2952

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/2952/ 题目讲一个细胞可分裂成 2 个,那么当前数目就是2a,a 为时间 然后 q 个细胞一起会死亡,也就是对 q 取 ...

  6. ie6浏览器兼容性

    1.ie6双倍边距bug 块状元素设置float(左浮动或有浮动),并且设置margin值之后,第一个浮动的元素其左侧margin值为正常的2倍,如图,可以看到第一个元素的左侧边距于其他元素两两之间的 ...

  7. 基于x64的处理器意思

    基于x64的处理器意思是CPU的架构是X64的,也是64位的CPU. 基本简介: "x86-64",有时会简称为"x64",是64位微处理器架构及其相应指令集的 ...

  8. C++高精度

    整理了一下高精度,虽然可用java,但很多时候还是C++写的方便. 附上kuangbin神的高精度模板(HDU1134 求卡特兰数) #include <iostream> #includ ...

  9. guake终端复制标签页

    平时习惯用的终端是下拉式终端guake,开多个标签各司其职,热键一按,呼之即来,挥之即去. 但用一个东西,就难免会有不爽的地方,比如每次想复制一个标签页,就要3步,1 新建标签页, 2 切换到之前的路 ...

  10. ZOJ 3598 Spherical Triangle球面几何公式应用

    #include <map> #include <set> #include <list> #include <cmath> #include < ...