zoukankan      html  css  js  c++  java
  • P4137 Rmq Problem / mex

    题意

    回滚莫队见这篇博客

    需要注意一个细节,写在代码注释里了。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2*1e5+10;
    const int maxt=500;
    int n,m,t,block,nowl,nowr,nowans,lastans;
    int a[maxn],L[maxt],R[maxt],pos[maxn],cnt[maxn],tmpcnt[maxn],ans[maxn];
    struct Query{int l,r,id;}qr[maxn];
    inline bool cmp(Query x,Query y){return pos[x.l]==pos[y.l]?x.r>y.r:pos[x.l]<pos[y.l];}
    inline void add(int x)
    {
    	if(a[x]>n+1)return;
    	cnt[a[x]]++;
    }
    inline void erase(int x)
    {
    	if(a[x]>n+1)return;
    	cnt[a[x]]--;
    	if(!cnt[a[x]])nowans=min(nowans,a[x]);
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	for(int i=1;i<=m;i++)scanf("%d%d",&qr[i].l,&qr[i].r),qr[i].id=i;
    	t=sqrt(n);block=n/t;
    	if(n%t)block++;
    	for(int i=1;i<=block;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    	for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    	nowl=1,nowr=n;
    	for(int i=1;i<=n;i++)if(a[i]<=n+1)cnt[a[i]]++;
    	while(cnt[nowans])nowans++;
    	int last=0;lastans=nowans;
    	sort(qr+1,qr+m+1,cmp);
    	for(int i=1;i<=m;i++)
    	{
    		if(pos[qr[i].l]==pos[qr[i].r])
    		{
    			int res=0;
    			for(int j=qr[i].l;j<=qr[i].r;j++)if(a[j]<=n+1)tmpcnt[a[j]]++;
    			while(tmpcnt[res])res++;
    			ans[qr[i].id]=res;
    			for(int j=qr[i].l;j<=qr[i].r;j++)if(a[j]<=n+1)tmpcnt[a[j]]--;
    			continue;
    		}
    		if(last!=pos[qr[i].l])
    		{
    			nowans=lastans;//这里把nowans赋成上次换块时候的答案。
    			while(nowr<n)add(++nowr);//这个可能消去nowans。
    			while(nowl<L[pos[qr[i].l]])erase(nowl++);
    			last=pos[qr[i].l];lastans=nowans;
    		}
    		while(nowr>qr[i].r)erase(nowr--);
    		int tmp=nowans,tmpl=nowl;
    		while(nowl<qr[i].l)erase(nowl++);
    		ans[qr[i].id]=nowans;
    		while(nowl>tmpl)add(--nowl);
    		nowans=tmp;
    	}
    	for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    [转] 《大腕》——编程高手篇
    [转] 如何用VB.Net创建一个三层的数据库应用程序
    [转] 张孝祥的java试题
    [转] 很久以前的一个sql面试题及答案.
    [转] C#编程实践
    [转] html技巧
    [转] 揭开SVCHOST.exe进程之谜
    [转] c#.net常用函数和方法集
    [转] Visual Studio.Net 快捷键表
    [转] left join/right join/inner join操作演示
  • 原文地址:https://www.cnblogs.com/nofind/p/12066398.html
Copyright © 2011-2022 走看看