zoukankan      html  css  js  c++  java
  • 【解题报告】洛谷P6852 Mex

    【解题报告】洛谷P6852 Mex

    题目链接

    https://www.luogu.com.cn/problem/P6852

    思路

    要求构造一个序列

    我们发现,对于一个区间 ([l,r])(mex)(val)([0,val-1]) 必须都出现在这个区间中,并且 (val) 不能出现在这个区间中

    所以我们对于某个值

    • (val=0)

    可以变成这个 (val) 必须出现的 一个区间,和不能出现的很多区间

    • (val ot =0)

    可以变成一个必须出现的区间和不能出现的区间,实际上就是把不能出现的区间并起来,剩下的就是能出现的区间了

    所以我们从小到大填入一个数字 (val) ,每次在 (val) 必须出现的区间中随便选一个点填进去

    然后我们用一个集合来维护可以选择的点,每次用二分确定还能选择符合要求的数字,且必须在区间的左端点,然后再判断它是不是在不能出现的区间里面,如果不在的话,填进去,否则不填进去,然后找不在这个区间只能的能填进去的下一个位置,然后重复上述步骤即可

    我们特判一下 (0) 的位置,然后就解决了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <set>
    using namespace std;
    const int maxn=500005;
    int n,m;
    int loc[maxn],roc[maxn];
    int lb[maxn],rb[maxn];
    int pre[maxn],ans[maxn];
    bool flag;
    set <int> s;
    int main()
    {
    	cin>>n>>m;
    	for(int i=0;i<=n;i++)
    	s.insert(i);
    	for(int i=0;i<=n+1;i++)
    	{
    		loc[i]=0,roc[i]=n;
    		lb[i]=n+1,rb[i]=-1;
    	}
    	for(int i=1;i<=m;i++)
    	{
    		int x,y,val;
    		cin>>x>>y>>val;
    		if(val)
    		{
    			loc[val-1]=max(loc[val-1],x);
    			roc[val-1]=min(roc[val-1],y);
    			lb[val]=min(lb[val],x),rb[val]=max(rb[val],y);
    		}
    		else
    		{
    			pre[x]++;
    			pre[y+1]--;
    		}
    	}
    	for(int i=n;i>=0;i--)
    	{
    		loc[i]=max(loc[i],loc[i+1]);
    		roc[i]=min(roc[i],roc[i+1]);
    	}
    	for(int i=0;i<=n;i++)
    	{
    		pre[i]+=pre[i-1];
    		if(loc[0]<=i&&i<=roc[0]&&pre[i]==0)
    		{
    			ans[i]=0;
    			s.erase(i);
    			break;
    		}
    	}
    	for(int i=1;i<=n;i++)
    	{
    		set <int>::iterator it=s.lower_bound(loc[i]);
    		if(it!=s.end()&&*it<=roc[i]&&(lb[i]>*it||*it>rb[i]))
    		{
    			ans[*it]=i;
    			s.erase(it);
    		}
    		else if(rb[i]!=-1)
    		{
    			it=s.lower_bound(rb[i]+1);
    			if(it!=s.end()&&*it<=roc[i])
    			{
    				ans[*it]=i;
    				s.erase(it);
    			}
    		}
    	}
    	if(s.size())
    	cout<<-1<<'
    ';
    	else
    	{
    		for(int i=0;i<=n;i++)
    		cout<<ans[i]<<" ";
    		cout<<'
    ';
    	}
    	return 0;
    }
    
    本博文为wweiyi原创,若想转载请联系作者,qq:2844938982
  • 相关阅读:
    js之oop <四>对象管理
    收集的一些前端面试题(持续更新)
    js之oop <三>属性标签
    js之oop <二> 对象属性
    js之oop <一> 创建对象,构造器(class)
    PHP_$_SERVER_说明详解
    利用jquery实现网站中对应栏目下面内容切换效果。
    网站中通知公告栏目滚动提示的效果
    图片上传利用<iframe></iframe>标签实现无刷新上传图片
    phpcms v9 数据库操作函数
  • 原文地址:https://www.cnblogs.com/wweiyi2004/p/15403983.html
Copyright © 2011-2022 走看看