zoukankan      html  css  js  c++  java
  • 【XSY2484】mex

    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

    3
    1 3 4
    3 1 6
    2 1 3
    

    Sample Output

    1
    3
    1
    

    HINT

    对于30%的数据1≤n≤1000,1≤l≤r≤1e18

    对于100%的数据1≤n≤100000,1≤l≤r≤1e18

    l,r最大可达1e18,肯定要离散化。

    有大量的区间修改的操作——考虑线段树

    解决方法:

    离散化+线段树

    首先离散化。

    离散化时将每一次操作的区间的l,r,r+1放入一个数组。lower_bound离散化,得到离散化后的l,r。

    为什么要放入r+1?

    像这样,离散化后,1-2,3-4区间都为1,本来应该有0的存在,但在线段树上却没有,这时候就要用r+1把这个“坑”给填上。

    离散化后:

    线段树记录(minn[i][0]),(minn[i][1]),表示在该区间0和1最早在哪个点出现,若没出现过,minn=INF;

    操作1,2: 区间修改(minn[i][0]),(minn[i][1]),(sum[i])懒标记。

    操作3: 交换(minn[i][0]),(minn[i][1]),(lazy[i])懒标记记录是否换了回来,若没换回来,pushdown。

    总体的思路就是这样了,代码有点难调试,一定要耐心打,用心调。

    #include<bits/stdc++.h>
    #define inf 1e9
    using namespace std;
    struct data
    {
    	int op;
    	long long l,r;
    }q[2000001];
    int lazy[2000001],minn[2000001][2],sum[2000001],op,n,cnt,cnt1;
    long long l,r,b[2000001];
    void build(int hao,int l,int r)
    {
    	lazy[hao]=0;
    	sum[hao]=-1;
    	minn[hao][0]=l;
    	minn[hao][1]=inf;
    	if(l==r)
    	{
    		return;
    	}
    	int mid=(l+r)/2;
    	build(hao<<1,l,mid);
    	build(hao<<1|1,mid+1,r);
    }
    void pushdown(int hao,int l,int r)
    {
    	int mid=(l+r)/2;
    	if(sum[hao]!=-1)//下放sum
    	{
    		int p=sum[hao];
    		sum[hao<<1]=sum[hao<<1|1]=p;
    		lazy[hao<<1]=lazy[hao<<1|1]=0;
    		minn[hao<<1][p]=l;
    		minn[hao<<1|1][p]=mid+1;
    		minn[hao<<1][p^1]=inf;
    		minn[hao<<1|1][p^1]=inf;
    		sum[hao]=-1;
    	}
    	if(lazy[hao])//下放lazy
    	{
    		lazy[hao<<1]^=1;
    		lazy[hao<<1|1]^=1;
    		swap(minn[hao<<1][0],minn[hao<<1][1]);
    		swap(minn[hao<<1|1][0],minn[hao<<1|1][1]);
    		lazy[hao]=0;
    	}
    }
    void update(int hao,int l,int r,int L,int R,int num)//操作1,2
    {
    	if(L<=l&&R>=r)
    	{
    		sum[hao]=num;
    		minn[hao][num]=l;
    		lazy[hao]=0;
    		minn[hao][num^1]=inf;
    	}else{
    		pushdown(hao,l,r);
    		int mid=(l+r)/2;
    		if(L<=mid)
    		{
    			update(hao<<1,l,mid,L,R,num);
    		}
    		if(R>mid)
    		{
    			update(hao<<1|1,mid+1,r,L,R,num);                                             
    		}
    		minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
    		minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
    	}
    }
    void change(int hao,int l,int r,int L,int R)//操作3
    {
    	if(L<=l&&R>=r)
    	{
    		lazy[hao]^=1;
    		swap(minn[hao][0],minn[hao][1]);
    	}else{
    		pushdown(hao,l,r);
    		int mid=(l+r)/2;
    		if(L<=mid)
    		{
    			change(hao<<1,l,mid,L,R);
    		}
    		if(R>mid)
    		{
    			change(hao<<1|1,mid+1,r,L,R);
    		}
    		minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
    		minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%lld%lld",&op,&l,&r);
    		q[i].op=op;
    		q[i].l=l;
    		q[i].r=r;
    		b[++cnt]=l;
    		b[++cnt]=r;
    		b[++cnt]=r+1;
    	}
    	b[++cnt]=1;
    	sort(b+1,b+cnt+1);
    	b[0]=-0x7f7f7f7f;
    	for(int i=1;i<=cnt;i++)//去重
    	{
    		if(b[i]==b[i-1])
    		{
    			continue;
    		}
    		b[++cnt1]=b[i];
    	}
    	cnt=cnt1;
    	build(1,1,cnt);
    	for(int i=1;i<=n;i++)
    	{
    		int l=lower_bound(b,b+cnt+1,q[i].l)-b;//离散化
    		int r=lower_bound(b,b+cnt+1,q[i].r+1)-b-1;
    		if(q[i].op==1)
    		{
    			update(1,1,cnt,l,r,1);
    		}else{
    			if(q[i].op==2)
    			{
    				update(1,1,cnt,l,r,0);
    			}else{
    				change(1,1,cnt,l,r);
    			}
    		}
    		printf("%lld
    ",b[minn[1][0]]);
    	}
    	return 0;
    }
    /*
    3
    1 3 4
    3 1 6
    2 1 3
    */
    
  • 相关阅读:
    获取CheckBoxList当前选择项索引
    IE游览器与CMYK模式的JPEG格式图片不兼容
    jquery listbox左右移动 并且取值
    JS保留2位小数
    list.Contain 与 list.FindIndex()用法记录
    CSS 手型显示样式
    分页存储过程
    C#将datatable生成easyui的绑定tree 的json数据格式
    URL编码方法的比较
    UNIX I/O with TCP/IP
  • 原文地址:https://www.cnblogs.com/2017gdgzoi44/p/11348762.html
Copyright © 2011-2022 走看看