ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

817 F. MEX Queries(线段树区间赋值+取反)

2021-02-01 16:30:56  阅读:315  来源: 互联网

标签:rt int sum rev 取反 li tag Queries 817


传送门

离散化询问,建立线段树

维护两个标记 t a g tag tag表示当前区间赋值为 0 / 1 0/1 0/1

r e v rev rev表示当前区间是否需要取反 0 / 1 0/1 0/1

p u s h d o w n pushdown pushdown的时候首先看 t a g tag tag标记,有 t a g tag tag标记直接抹除所有 r e v rev rev标记

再看 r e v rev rev标记,把区间取反即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mid (l+r>>1)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
const int maxn = 1e6+10;
int type[maxn],l[maxn],r[maxn],li[maxn],n,m;
int sum[maxn<<1],tag[maxn<<1],rev[maxn<<1];
void pushdown(int rt,int l,int r)//赋值操作和翻转操作不会同时存在 
{
	if( tag[rt]!=-1 )//需要赋值 
	{
		tag[ls] = tag[rs] = tag[rt];
		sum[ls] = (mid-l+1)*tag[rt], sum[rs] = (r-mid)*tag[rt];
		rev[ls] = rev[rs] = 0;
		tag[rt] = -1;
	}
	if( rev[rt] )//需要翻转 
	{
		rev[ls] ^= 1; rev[rs] ^= 1;
		sum[ls] = mid-l+1-sum[ls]; sum[rs] = r-mid-sum[rs];
		rev[rt] = 0;
	}
}
void update(int rt,int l,int r,int L,int R,int val)//把L,R都变成val 
{
	if( l>R||r<L )	return;
	if( l>=L&&r<=R )
	{
		sum[rt] = (r-l+1)*val; tag[rt] = val; rev[rt] = 0;
		return; 
	}
	pushdown(rt,l,r);
	update(lson,L,R,val); update(rson,L,R,val);
	sum[rt] = sum[ls]+sum[rs];
}
void XOR(int rt,int l,int r,int L,int R)
{
	if( l>R||r<L )	return;
	if( l>=L&&r<=R )//区间异或 
	{
		sum[rt] = r-l+1-sum[rt];	
		rev[rt] ^= 1; 
		return;
	}
	pushdown(rt,l,r);
	XOR(lson,L,R); XOR(rson,L,R);
	sum[rt] = sum[ls]+sum[rs];
}
int ask(int rt,int l,int r)
{
	if( l==r )	return l;
	pushdown(rt,l,r);
	if( sum[ls]<mid-l+1 )	return ask(ls,l,mid);
	else	return ask(rs,mid+1,r);	
}
signed main()
{
	scanf("%lld",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&type[i],&l[i],&r[i] );
		li[++n] = l[i], li[++n] = r[i], li[++n] = r[i]+1;
	}
	li[++n] = 1;
	sort( li+1,li+1+n );
	n = unique(li+1,li+1+n)-li-1;
	memset( tag,-1,sizeof tag );
	for(int i=1;i<=m;i++)
	{
		l[i] = lower_bound(li+1,li+1+n,l[i] )-li;
		r[i] = lower_bound(li+1,li+1+n,r[i] )-li;	
		if( type[i]==1 )
			update(1,1,n,l[i],r[i],1 );
		else if( type[i]==2 )
			update(1,1,n,l[i],r[i],0 );
		else
			XOR(1,1,n,l[i],r[i] );
		printf("%lld\n",li[ask(1,1,n)] );
	}
}

标签:rt,int,sum,rev,取反,li,tag,Queries,817
来源: https://blog.csdn.net/jziwjxjd/article/details/113523315

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有