题意

维护一个01串,一开始全部都是0

3种操作

1.把一个区间都变为1

2.把一个区间都变为0

3.把一个区间的所有数字翻转过来

每次操作完成之后询问区间最小的0的位置

l,r<=10^18

题解

区间操作想到线段树,离散化不用说,l,r太大了。

1,2,3操作非常好维护。

然后在查询中二分查询就好了。

一开始看别的博客说要加1节点和r+1节点不知道为什么。

因为我的查询想的是,查询前面全都是1的区间的长度。后来发现做不了。就乖乖照题解做了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
const long long N=;
map<long long,long long> mp;
long long b[N*],n,m,cnt;
struct ask{
long long l,r;
long long k;
}q[N];
struct tree{
long long l,r,sum,sev,lazy;
}tr[N*];
void build(long long l,long long r,long long now){
tr[now].l=l;
tr[now].r=r;
tr[now].lazy=-;
if(l==r)return;
long long mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
}
void pushdown(long long now){
long long mid=(tr[now].l+tr[now].r)>>;
if(tr[now].lazy!=-){
tr[now*].lazy=tr[now*+].lazy=tr[now].lazy;
tr[now*].sum=(mid-tr[now].l+)*tr[now].lazy;
tr[now*+].sum=(tr[now].r-mid)*tr[now].lazy;
tr[now*].sev=tr[now*+].sev=;
tr[now].lazy=-;
}
if(tr[now].sev){
tr[now*].sev^=;
tr[now*+].sev^=;
tr[now*].sum=(mid-tr[now].l+)-tr[now*].sum;
tr[now*+].sum=(tr[now].r-mid)-tr[now*+].sum;
tr[now].sev=;
}
}
void update(long long l,long long r,long long now,long long k){
// cout<<l<<" "<<r<<" "<<tr[now].l<<" "<<tr[now].r<<" "<<now<<endl;
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].sum=(tr[now].r-tr[now].l+)*k;
tr[now].lazy=k;
tr[now].sev=;
return ;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid){
update(l,r,now*+,k);
}
else if(r<=mid){
update(l,r,now*,k);
}
else{
update(l,mid,now*,k);
update(mid+,r,now*+,k);
}
tr[now].sum=tr[now*].sum+tr[now*+].sum;
}
void serve(long long l,long long r,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].sum=(tr[now].r-tr[now].l+)-tr[now].sum;
tr[now].sev^=;
return;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)serve(l,r,now*+);
else if(r<=mid)serve(l,r,now*);
else{
serve(l,mid,now*);
serve(mid+,r,now*+);
}
tr[now].sum=tr[now*].sum+tr[now*+].sum;
}
void check(long long now){
if(tr[now].l==tr[now].r){
printf("%lld\n",b[tr[now].l]);
return ;
}
long long mid=(tr[now].l+tr[now].r)>>;
pushdown(now);
if(tr[now*].sum<mid-tr[now].l+)check(now*);
else return check(now*+);
}
int main(){
scanf("%lld",&m);
for(long long i=;i<=m;i++){
scanf("%lld%lld%lld",&q[i].k,&q[i].l,&q[i].r);
q[i].r++;
b[++cnt]=q[i].l;
b[++cnt]=q[i].r;
}
b[++cnt]=;
sort(b+,b++cnt);
n=unique(b+,b++cnt)-(b+);
for(long long i=;i<=n;i++){
mp[b[i]]=i;
}
build(,n,);
for(long long i=;i<=m;i++){
if(q[i].k==){
update(mp[q[i].l],mp[q[i].r]-,,);
}
else if(q[i].k==){
update(mp[q[i].l],mp[q[i].r]-,,);
}
else{
serve(mp[q[i].l],mp[q[i].r]-,);
}
check();
}
return ;
}

CF817F MEX Queries(线段树上二分)的更多相关文章

  1. HDU 4747 Mex【线段树上二分+扫描线】

    [题意概述] 一个区间的Mex为这个区间没有出现过的最小自然数,现在给你一个序列,要求求出所有区间的Mex的和. [题解] 扫描线+线段树. 我们在线段树上维护从当前左端点开始的前缀Mex,显然从左到 ...

  2. LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分

    题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...

  3. 贪心+离散化+线段树上二分。。。 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest G. Of Zorcs and Axes

    题目链接:http://codeforces.com/gym/101149/problem/G 题目大意:给你n对数字,为(a[i], b[i]),给你m对数字,为(w[i], c[i]).给n对数字 ...

  4. 【BZOJ】4293: [PA2015]Siano 线段树上二分

    [题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...

  5. hdu 5930 GCD 线段树上二分/ 强行合并维护信息

    from NOIP2016模拟题28 题目大意 n个点的序列,权值\(<=10^6\) q个操作 1.单点修改 2.求所有区间gcd中,不同数个数 分析 1.以一个点为端点,向左或向右的gcd种 ...

  6. [NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)

    Description “我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力.”——<The Grimoire of Marisa>雾雨魔理 ...

  7. 【洛谷5537】【XR-3】系统设计(哈希_线段树上二分)

    我好像国赛以后就再也没有写过 OI 相关的博客 qwq Upd: 这篇博客是 NOIP (现在叫 CSP 了)之前写的,但是咕到 CSP 以后快一个月才发表 -- 我最近这么咕怎么办啊 -- 题目 洛 ...

  8. 5.4 省选模拟赛 修改 线段树优化dp 线段树上二分

    LINK:修改 题面就不放了 大致说一下做法.不愧是dls出的题 以前没见过这种类型的 不过还是自己dp的时候写丑了. 从这道题中得到一个结论 dp方程要写的优美一点 不过写的过丑 优化都优化不了. ...

  9. 9 16 模拟赛&关于线段树上二分总结

    1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...

随机推荐

  1. Elasticsearch之下载源码

    第一步:进入github.com 第二步: 第三步: 第四步: 第五步: 第六步: 第七步:认识下es的源码目录结构

  2. 【原创】VMWare克隆或复制Linux虚拟机后无法上网的解决

    如果选择桥接,需要设置网卡通过哪个物理网卡桥接,桥接代表当前虚拟机通过本机的网卡直接连到网络中,本机网卡作为一个交换机直连.因此需要确定使用哪个网卡桥接,一般在单网卡的时候选择自动即可,多网卡时需要指 ...

  3. firewall 实现数据的端口转发

    端口转发:firewall-cmd --add-port=80/tcp firewall-cmd --add-port=10050/tcp firewall-cmd --add-forward-por ...

  4. [arc076f]Exhausted? - 贪心

    题意: 给你m个椅子可以坐人,初始坐标为正整数1~m,有n个人,每个人希望坐的位置$\leq L_i$或者$\geq R_i$,可以添加若干个椅子在任意的实数位置,求最少要添加多少椅子使得所有人都有位 ...

  5. FFT&NTT学习笔记

    具体原理就不讲了qwq,毕竟证明我也不太懂 FFT(快速傅立叶变换)&NTT(快速数论变换) FFT //求多项式乘积 //要求多项式A和多项式B的积多项式C //具体操作就是 //DFT(A ...

  6. omi-mp-create源码加注

    omi-mp-create是dntzhang写的小程序框架,主要功能是实现全局状态自动更新和页面间通信,传送门. 代码虽然简单但是注释不多读起来还是需要一点时间理解,因此在上面加入了个人理解的注释方便 ...

  7. spring慕课网

    资源链接 http://spring.io/ http://projects.spring.io/spring-framework/ Spring是什么? Spring是一个开源的轻量级的应用开发框架 ...

  8. 使用systemctl自定义系统服务

    1.创建系统服务文件,格式如下: [Unit] Description=httpd After=network.target [Service] Type=forking ExecStart=/usr ...

  9. Linux一些简单命令

    1.安装gvim:sudo apt-get install vim-gtk vim和gvim相同,只是后者比前者多了一个界面,此界面可以用来保存.新建.查找等. 三种模式,insert(i),norm ...

  10. 2015 Multi-University Training Contest 3 hdu 5316 Magician

    Magician Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...