正解:主席树
解题报告:
本来以为是道入门无脑板子题,,,然后康了眼数据范围发现并没有我想像的那么简单昂$kk$
这时候看到$n$的范围不大,显然考虑离散化?但是又感觉似乎布星?因为询问的是最小没有出现昂$kk$
这时候考虑到答案显然要么是0要么是$a_{i}+1$?所以只用把$0,a_{i},a_{i}+1$离散化掉就成$QwQ$
然后就主席树板子了$QwQ$?开权值线段树存这个位置当前最后一次出现的位置,然后每次就是找最小的最后一次出现位置<l的数就成$QwQ$
$overrrrr$
对了,说一句,就记得数组要开大点儿,,,我数组开小了它也没有提醒我$RE$了而是跟我港$WA$了$QAQQQQQ$
#include<bits/stdc++.h> using namespace std; #define il inline #define int long long #define gc getchar() #define ri register int #define rc register char #define rb register bool #define rp(i,x,y) for(ri i=x;i<=y;++i) #define my(i,x,y) for(ri i=x;i>=y;--i) #define lb(x) lower_bound(st+1,st+1+sum,x)-st const int N=500000+10; int n,m,a[N],st[N],sum,rt[N],tr_cnt; struct node{int mn,ls,rs;}tr[N<<5]; il int read() { rc ch=gc;ri x=0;rb y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')ch=gc,y=0; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } int insert(ri d,ri l,ri r,ri dat,ri pos) { ri nw=++tr_cnt;tr[nw]=tr[d];if(l==r)return tr[tr_cnt].mn=pos,tr_cnt; ri mid=(l+r)>>1;mid>=dat?tr[nw].ls=insert(tr[d].ls,l,mid,dat,pos):tr[nw].rs=insert(tr[d].rs,mid+1,r,dat,pos); tr[nw].mn=min(tr[tr[nw].ls].mn,tr[tr[nw].rs].mn);return nw; } int query(ri nw,ri l,ri r,ri to) { if(l==r)return l; //printf("nw=%d l=%d r=%d to=%d ls.mn=%d ",nw,l,r,to,tr[tr[nw].ls].mn); if(tr[tr[nw].ls].mn<to)return query(tr[nw].ls,l,(l+r)>>1,to); return query(tr[nw].rs,((l+r)>>1)+1,r,to); } signed main() { freopen("4137.in","r",stdin);freopen("4137.out","w",stdout); n=read();m=read();rp(i,1,n)a[i]=st[++sum]=read(),st[++sum]=a[i]+1;st[++sum]=0; sort(st+1,st+1+sum);sum=unique(st+1,st+1+sum)-st-1;rp(i,1,n)rt[i]=insert(rt[i-1],1,sum,lb(a[i]),i); while(m--){ri l=read(),r=read();printf("%lld ",st[query(rt[r],1,sum,l)]);} return 0; }