zoukankan      html  css  js  c++  java
  • CF1436E Complicated Computations 线段树维护区间mex

    题意:求一个序列所有连续子序列的mex值的mex

    考虑一个数可以成为一段连续子序列的mex,首先没有在子序列里面出现过,且所有小于该数的正整数均在此子序列中出现过。

    那么验证一个数$x$是否可以成为mex,整个序列被$x$划分为多个区间,按照权值建一棵线段树维护每个权值出现的最晚位置的最小值。

    $1sim n$:当移动到$a[i]$时,看权值为$1sim a[i]-1$的数出现的最晚位置是否都大于$a[i]$上次出现的位置$last[a[i]]$.

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int n,a[maxn],last[maxn];
    bool vis[maxn];
    struct Node{
    	int Min;
    }tree[maxn<<2];
    void update(int rt,int l,int r,int pos,int x) {
    	if(l==r) {
    		tree[rt].Min=x;
    		return;
    	}
    	int mid=l+r>>1;
    	if(pos<=mid) update(rt<<1,l,mid,pos,x);
    	else update(rt<<1|1,mid+1,r,pos,x);
    	tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
    }
    int query(int rt,int l,int r,int L,int R) {
    	if(L<=l&&R>=r) return tree[rt].Min;
    	int mid=l+r>>1,res=0x3f3f3f3f;
    	if(L<=mid) res=query(rt<<1,l,mid,L,R);
    	if(R>mid) res=min(res,query(rt<<1|1,mid+1,r,L,R));
    	return res;
    }
    int main() {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) {
    		scanf("%d",&a[i]);
    		if(a[i]!=1) vis[1]=1;
    		if(a[i]>1&&query(1,1,n,1,a[i]-1)>last[a[i]]) vis[a[i]]=1;
    		last[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)>last[i]) vis[i]=1;
    	int ans=1;
    	while(vis[ans]) ans++;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    一次线上bug引起的反思
    本地调试接口返回信息不对 以及 jar冲突问题
    404问题记录
    Intelij IDEA 配置Tomcat时找不到 “Application Server”
    java多线程处理问题
    DataTemplate和ControlTemplate的关系
    WP模板
    wp中的动画
    wp中的位图
    2013.7.22-7.28开发资料汇总
  • 原文地址:https://www.cnblogs.com/1999-09-21Karry-erfs/p/14274105.html
Copyright © 2011-2022 走看看