题解 P4137 Rmq Problem / mex
因为 \(mex < n\) ,所以修改时对于 \(a_{i} \ge n\) ,可将其特判掉。
故剩余的 \(a_{i}\) 都有 \(a_{i} < n\) ,此时可用桶记录每个数出现的次数。
按莫队正常操作排序后,再对每次两个区间的不同部分暴力修改。
发现会超时。只要加一个小优化即可通过:
在排序的时候,判断对于第 \(i,j\) 个结构体 \(q_{i}\) 和 \(q_{j}\) ,是否有
\(\frac{q_{i}.l}{\sqrt{n}} < \frac{q_{j}.l}{\sqrt{n}}\)
如果是就直接排序;否则判断是否有
\(q_{i}.r < q_{j}.r\)
如果是就直接排序;否则按
\(q_{i}.l < q_{j}.l\)
排序。
\(code\)
#include<cstdio>
#include<algorithm>
#include<cmath>
#define R register
using namespace std;
int n,m,sqn;
int a[200002],bel[200002],num[200002]={};
struct aaa
{
int l,r,num,ans;
}q,qry[200002];
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0' || ch>'9')f|=(ch=='-'),ch=getchar();
while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
x=f? -x:x;return ;
}
inline bool cmp(aaa a,aaa b)
{
return (bel[a.l]==bel[b.l])? ((a.r==b.r)? (a.l<b.l):(a.r<b.r)):(bel[a.l]<bel[b.l]);
}
inline bool cmp1(aaa a,aaa b)
{
return a.num<b.num;
}
int main()
{
read(n),read(m),sqn=n/sqrt(m);
for(R int i=1;i<=n;++i)read(a[i]),bel[i]=i/sqn;
for(R int i=1;i<=m;++i)read(qry[i].l),read(qry[i].r),qry[i].num=i;
int l=1,r=0,now_ans=0;sort(qry+1,qry+m+1,cmp);
for(R int i=1;i<=m;++i)
{
q=qry[i];if(q.l>q.r){qry[i].ans=0;continue;}
while(l>q.l){if(a[--l]<n)++num[a[l]];while(num[now_ans])++now_ans;}
while(r<q.r){if(a[++r]<n)++num[a[r]];while(num[now_ans])++now_ans;}
while(l<q.l){if(a[l]<n && !(--num[a[l]]) && a[l]<now_ans)now_ans=a[l];++l;}
while(r>q.r){if(a[r]<n && !(--num[a[r]]) && a[r]<now_ans)now_ans=a[r];--r;}
qry[i].ans=now_ans;
}
sort(qry+1,qry+m+1,cmp1);
for(R int i=1;i<=m;++i)printf("%d\n",qry[i].ans);
return 0;
}