zoukankan      html  css  js  c++  java
  • bzoj 3585 mex

    Written with StackEdit.

    题目描述

    有一个长度为(n)的数组({a_1,a_2,...,a_n})(m)次询问,每次询问一个区间内最小没有出现过的自然数。

    Input

    第一行(n,m)
    第二行为(n)个数。
    从第三行开始,每行一个询问(l,r)

    Output

    一行一个数,表示每个询问的答案。

    Sample Input

    5 5
    2 1 0 2 1
    3 3
    2 3
    2 4
    1 2
    3 5

    Sample Output

    1
    2
    3
    0
    3

    HINT

    对于(30\%)的数据:
    (1<=n,m<=1000.)

    对于(100\%)的数据:
    (1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n.)

    Solution

    • 多个区间询问,可以离线,并且可以(O(1))转移,考虑使用莫队.
    • 但是(a_ileq 10^9),直接开个(cnt)数组记录当前区间内的各种个数似乎不可做?
    • 然而,对于大于(n)的元素,我们可以直接无视它.
    • 一方面,它一定不会成为答案,否则需要出现至少(0)~(n)(n+1)个数.
    • 另一方面,它肯定不会对答案做出贡献.否则答案也会大于(n),据上,不可能.
    • 所以(a_i)的范围只是虚张声势...我们处理时将大于(n)的数都视作(n+1)即可.
    • 然后就是一个愉快的莫队板子题了.
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LoveLive;
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		{
    			fh=-1;
    			jp=getchar();
    		}
    	while (jp>='0'&&jp<='9')
    		{
    			out=out*10+jp-'0';
    			jp=getchar();
    		}
    	return out*fh;
    }
    const int MAXN=2e5+10;
    int cnt[MAXN];
    set<int> s;
    int Ans[MAXN];
    int n,m;
    int a[MAXN];
    int belong[MAXN],BlockSize;
    int L,R,res;
    struct Query{
    	int l,r;
    	int id;
    	bool operator < (const Query &rhs) const 
    		{
    			if(belong[l]!=belong[rhs.l])
    				return belong[l]<belong[rhs.l];
    			return belong[r]<belong[rhs.r];
    		}
    }q[MAXN];
    void BuildBlocks()
    {
    	BlockSize=sqrt(n);
    	for(int i=1;i<=n;++i)
    		belong[i]=(i/BlockSize)+1;
    }
    void add(int pos)
    {
    	++cnt[a[pos]];
    	for(int i=res;i<=n+2;++i)
    		if(cnt[i]==0)
    			{
    				res=i;
    				return;
    			}
    }
    void remove(int pos)
    {
    	--cnt[a[pos]];
    	if(cnt[a[pos]]==0)
    		res=min(res,a[pos]);
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;++i)
    		a[i]=read(),a[i]=a[i]>n?n+1:a[i];
    	for(int i=1;i<=m;++i)
    		{
    			q[i].id=i;
    			q[i].l=read();
    			q[i].r=read();		
    		}
    	for(int i=0;i<=n;++i)
    		s.insert(i);
    	a[0]=n+2;
    	BuildBlocks();
    	sort(q+1,q+1+m);
    	L=0,R=0;
    	for(int i=1;i<=m;++i)
    		{
    			int l=q[i].l,r=q[i].r;
    			while(L<l)
    				remove(L),++L;
    			while(L>l)
    				--L,add(L);
    			while(R<r)
    				++R,add(R);
    			while(R>r)
    				remove(R),--R;
    			Ans[q[i].id]=res;
    		}
    	for(int i=1;i<=m;++i)
    		printf("%d
    ",Ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    环境是如何建立的 启动文件有什么
    环境中存储的是什么
    串行 并行 异步 同步
    TPC-H is a Decision Support Benchmark
    进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
    删除环境变量
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
  • 原文地址:https://www.cnblogs.com/jklover/p/10105545.html
Copyright © 2011-2022 走看看