Educational Codeforces Round 23 F. MEX Queries(离散化+线段树)

题目链接:http://codeforces.com/contest/817/problem/F


这个题的难度不像是F啊。。。


然而


我好蠢啊。。。


最开始发现,其实很多区间可以合并在一起,就写了一个延时更新的[1,1e18]的线段树,MLE 21到死。。。


后来发现,离散化一下好像很清真啊?


由于只有0和1两个值,然后发现操作3就是个异或的操作,下放的时候可以同时对1的个数和lazy标记同时进行处理。离散化的时候,注意,对于区间[L,R],需要多离散化一个R+1这个节点,因为这个点可能作为某次查询的答案(别问我为啥离散化L-1,大概是蠢吧),然后就是个水题啊?


(那我为什么写了这么久啊?)


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct seg
{
	ll tot;
	bool rev;
	int lazy;
	bool ro;
	seg *lson,*rson;
	seg(){}
	seg(int _rev):rev(_rev)
	{
		lson=rson=NULL;
		lazy=-1;tot=0;
		ro=false;
	}
	ll gettot()
	{
		return tot;
	}
	void pushup()
	{
		ll ret=0;
		if(lson!=NULL)
			ret+=lson->gettot();
		if(rson!=NULL)
			ret+=rson->gettot();
		tot=ret;
	}
	int getid()
	{
		return lazy^rev;
	}
	void pushlazy(ll l,ll r)
	{
		ll mid=(l+r)>>1;
		if(lson==NULL)
			lson=new seg(0);
		if(rson==NULL)
			rson=new seg(0);
		if(ro)
		{
			lson->rev^=1;lson->ro=!lson->ro;
			lson->tot=(mid-l+1)-lson->tot;
			rson->rev^=1;rson->ro=!rson->ro;
			rson->tot=(r-(mid+1)+1)-rson->tot;
			ro=false;
		}
		if(lazy!=-1)
		{
			lson->lazy=(getid()^lson->rev);
			lson->tot=(mid-l+1)*lson->getid();
			rson->lazy=(getid()^rson->rev);
			rson->tot=(r-(mid+1)+1)*rson->getid();
			lazy=-1;
		}
	}
	void update(ll L,ll R,int val,bool we,ll l,ll r)
	{
		if(L<=l&&r<=R)
		{
			if(!we)
			{
				lazy=val^rev;
				tot=(r-l+1)*getid();
			}
			else
			{
				ro=!ro;
				rev^=1;
				tot=r-l+1-tot;
			}
			return ;
		}
		pushlazy(l,r);
		ll mid=(l+r)>>1;
		if(mid>=L)
		{
			lson->update(L,R,val,we,l,mid);
		}
		if(mid<R)
		{
			rson->update(L,R,val,we,mid+1,r);
		}
		pushup();
	}
	ll query(ll l,ll r)
	{
		if(gettot()==0)
			return l;
		ll mid=(l+r)>>1;
		seg tmp=*this;
		pushlazy(l,r);
		if(lson->gettot()<(mid-l+1))
			return lson->query(l,mid);
		else
			return rson->query(mid+1,r);
	}
}*root;
const int MAXN=1e5+5;
int tot;
ll Hash[MAXN*4];
struct qu
{
	int op;
	ll l,r;
}sv[MAXN];
int fi(ll now)
{
	int ret=lower_bound(Hash,Hash+tot,now)-Hash;
	return ret;
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	root=new seg(0);
	tot=0;
	Hash[tot++]=1000000000000000001LL;
	Hash[tot++]=1;
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int op;
		ll l,r;
		scanf("%d%lld%lld",&sv[i].op,&sv[i].l,&sv[i].r);
		Hash[tot++]=sv[i].l;Hash[tot++]=sv[i].r;
		if(sv[i].l!=1)
			Hash[tot++]=sv[i].l-1;
		Hash[tot++]=sv[i].r+1;
	}
	sort(Hash,Hash+tot);
	tot=unique(Hash,Hash+tot)-Hash;
	for(int i=1;i<=n;i++)
	{
		sv[i].l=fi(sv[i].l);
		sv[i].r=fi(sv[i].r);
	}
	for(int i=1;i<=n;i++)
	{
		if(sv[i].op==1)
		{
			root->update(sv[i].l,sv[i].r,1,false,0,tot-1);
		}
		if(sv[i].op==2)
		{
			root->update(sv[i].l,sv[i].r,0,false,0,tot-1);
		}
		if(sv[i].op==3)
		{
			root->update(sv[i].l,sv[i].r,0,true,0,tot-1);
		}
		int ret=root->query(0,tot-1);
		ll ans;
		ans=Hash[ret];
		printf("%lld\n",ans);
	}
	return 0;
}


"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值