zoukankan      html  css  js  c++  java
  • 题解 CF1436E 【Complicated Computations】

    题意:

    n个数,对所有子区间求mex,

    把答案组成新的一列数,再求mex。

    分析:

    先加入数值 (∈[1,i]) 的数,

    然后查询是否存在符合条件的区间有i-1个种数。

    条件:“两个为i的数之间”或“到a[i]的前缀”
    或“从a[i]到结尾”

    (有i-1种,说明有连续[1,i-1],mex可能是i,不可能是答案)。


    用线段树解决。

    t[x]保存的是x最后一次出现的地方,线段树维护区间最小值。

    扫到a[i]的时候,设m为[1,a[i]-1]中,出现最早的数所在的位置。

    如果m>上一个a[i]出现的位置,

    就说明存在两个为a[i]的数之间有a[i]-1个数,mex可以为a[i]。

    这样就解决了。

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,x,y) for(int i=x;i<=y;i++)
    #define per(i,x,y) for(int i=x;i>=y;i--)
    #define rd(x) scanf("%d",&x);
    typedef long long LL;
    const int N=1e5+10;
    int n,a[N],t[N<<2],las[N],f[N]; 
    void pushup(int rt){ t[rt]=min(t[rt<<1],t[rt<<1|1]); }
    int query(int rt,int l,int r,int L,int R){
    //	cout<<rt<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<endl;
    	if(l>R||r<L) return 1e9;
    	if(L<=l&&r<=R){
    	//	cout<<rt<<"*"<<t[rt]<<endl;
    		return t[rt];
    	}
    	int mid=l+r>>1;
    	return min(query(rt<<1,l,mid,L,R),query(rt<<1|1,mid+1,r,L,R));
    }
    void update(int rt,int l,int r,int x,int val){
    //	cout<<rt<<"*"<<l<<" "<<r<<" "<<x<<" "<<val<<endl;
    	if(x<l||x>r) return;
    	if(l==r) { t[rt]=val; return; }
    	int mid=l+r>>1;
    	update(rt<<1,l,mid,x,val);
    	update(rt<<1|1,mid+1,r,x,val);
    	pushup(rt);
    	return;
    }
    int main(){
    	rd(n);
    	rep(i,1,n){
    		rd(a[i]);
    		int x=0; if(a[i]!=1) x=query(1,1,n,1,a[i]-1);
    	//	cout<<a[i]<<" "<<x<<endl;
            //[1,a[i]-1]中最早出现的数(每次维护的都是每个数最晚出现的地点)晚于于lst[a[i]]
    		//两个a[i]之间有集齐i-1个
    		// 存在mex为a[i]的子区间
    		if(x>las[a[i]]) f[a[i]]=1;
    		update(1,1,n,a[i],i);las[a[i]]=i;
    	}
    	rep(i,2,n+1){
    		int x=query(1,1,n,1,i-1);
    		if(x>las[i]) f[i]=1;
    	}//结尾再统计一次 
    	rep(i,1,n) if(a[i]!=1) f[1]=1;
    	int i=1;
    	while(1){
    		if(f[i]==0){
    			printf("%d
    ",i);
    			return 0;
    		}
    		i++;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    js上传文件
    IOS怎么实现一个UITableView的下拉刷新
    Android的事件处理-android学习之旅(四十四)
    NIO框架之MINA源代码解析(二):mina核心引擎
    每日五题
    Joda-Time 简介
    用websocket实现后台推送消息
    websoclet简单示例 my 改
    struts2拦截器interceptor的配置方法及使用
    activiti复盘重推的一种简单实现方式:
  • 原文地址:https://www.cnblogs.com/zdsrs060330/p/13882610.html
Copyright © 2011-2022 走看看