• CF1436E Complicated Computations 题解


    Problem

    给定一个长度为 (n(n leq 10^5)) 的数组,求出它所有子数组 (MEX)(MEX)

    这里的(MEX) 定义为一个数组中第一个没有出现的 正整数

    Solution

    考场没有想出来,自闭了。

    我们考虑是否存在一个子数组,满足其(MEX=a) ,首先,这个子数组里面必须要没有 (a)

    于是我们首先把数组中所有的 (a) 找出来,这些 (a) 把数组分成了若干段,我们要的子数组必须不能跨越这些段。

    其次,对于这些段中,如果所有小于(a-1)的数都在里面,那么这一段一定满足(MEX=a) (因为里面没有(a))。

    可以结合一下图理解。

    CF1436E

    我们可以用线段树维护,具体细节见代码。

    Code

    const int MAXN = 1e5+10;
    
    int val[MAXN<<2],lst[MAXN],a[MAXN],n;
    bool able[MAXN];
    
    //这个线段树维护的是每个数最后出现的位置
    
    void update(int o,int l,int r,int pos,int v){
    	if(l == r) return (void)(val[o] = v);
    	int mid = l+r>>1;
    	if(pos <= mid) update(o<<1,l,mid,pos,v);
    	else update(o<<1|1,mid+1,r,pos,v);
    	val[o] = min(val[o<<1],val[o<<1|1]);
    }//更新区间最小值
    
    int query(int o,int l,int r,int xl,int xr){
    	if(l == xl && r == xr) return val[o];
    	int mid = l+r>>1;
    	if(xr <= mid) return query(o<<1,l,mid,xl,xr);
    	else if(xl > mid) return query(o<<1|1,mid+1,r,xl,xr);
    	else return min(query(o<<1,l,mid,xl,mid),query(o<<1|1,mid+1,r,mid+1,xr));
    }//查询区间最小值
    
    int main (){//lst[i] i 上一次出现的位置
    	scanf("%d",&n);
    	for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
    	for(int i = 1;i <= n;i++){
    		if(a[i] != 1) able[1] = 1;//注意对1的特判
    		if(a[i] > 1  && query(1,1,n,1,a[i]-1) > lst[a[i]]) able[a[i]] = 1;
          //对段进行分割处理(lst[a[i]] ~ i) ,如果 1~a[i]-1 的数最后出现的位置都 > lst[a[i]] 且 < i(因为后面的还没更新,所以必定 < i) ,那么这一段满足MEX = a[i]
    		lst[a[i]] = i;
    		update(1,1,n,a[i],i);
    	}
    	for(int i = 2;i <= n+1;i++) if(query(1,1,n,1,i-1) > lst[i]) able[i] = 1;
      //因为lst[i] 初始为0,所以之前我们处理了 1~i 最先出现的位置的段,但是没有处理 lst[i] ~ 结尾 的段,这里在处理一遍
    	int ans = 1;
    	for(;able[ans] && ans <= n+1;ans++);
      //查找答案,注意ans 上界实际上为 n+2
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Android图像格式类及图像转换方法
    Java实现文件的加密与解密
    Google最新截屏案例详解
    Android应用程序模拟手机按键
    Android浮动小球与开机自启动
    Android手机截屏
    Android图片浏览器之图片删除
    Android图片浏览器之缩略图
    MFC实现Gif动画制作工具
    QRadioButton分组且无边框的简单实现
  • 原文地址:https://www.cnblogs.com/werner-yin/p/-solution-CF-1436E.html
Copyright © 2020-2023  润新知