两题本质是一样,只不过3585要离散化
这种不修改,不强制的问题,显然先考虑离线算法
这道题的思路和bzoj1878非常像
考虑到如果只是求每个前缀的mex,我们是很容易扫一遍就得出来的
我们设为这个位置的mex
考虑从左往右依次删除当前数会对后面产生什么影响
我们设删除数a[i],a[i]下一个相同数的位置为next[a[i]]
显然对于[i+1,next[a[i]]-1]这些位置的mex可能有影响(如过没有next,就说明对后面所有位置都可能有影响);
凡是大于a[i]的一律都变成了a[i]
因此我们考虑对每个询问按左端点排序
然后从左往右依次删除a[i](按上述对后面位置进行修改)
不难发现,当某个询问左端点=当前位置i时(当然是先查询后删除了),这个询问的答案就是右端点上的mex,
显然修改操作我们可以用线段树来维护,这样就解决了这个问题
1 const inf=500010; 2 var loc,ans,next,last,sg,p,q,c,a,b:array[0..200010] of longint; 3 tree:array[0..800010] of longint; 4 d:array[0..400010] of longint; 5 v:array[0..400010] of boolean; 6 i,n,m,j,t,k:longint; 7 8 procedure swap(var a,b:longint); 9 var c:longint; 10 begin 11 c:=a; 12 a:=b; 13 b:=c; 14 end; 15 16 function min(a,b:longint):longint; 17 begin 18 if a>b then exit(b) else exit(a); 19 end; 20 21 function find(x:longint):longint; 22 var l,r,m:longint; 23 begin 24 l:=1; 25 r:=t; 26 while l<=r do 27 begin 28 m:=(l+r) shr 1; 29 if d[m]=x then exit(m); 30 if d[m]>x then r:=m-1 else l:=m+1; 31 end; 32 end; 33 34 procedure sort1(l,r:longint); 35 var i,j,x,y: longint; 36 begin 37 i:=l; 38 j:=r; 39 x:=p[(l+r) div 2]; 40 repeat 41 while p[i]<x do inc(i); 42 while x<p[j] do dec(j); 43 if not(i>j) then 44 begin 45 swap(p[i],p[j]); 46 swap(q[i],q[j]); 47 swap(c[i],c[j]); 48 inc(i); 49 j:=j-1; 50 end; 51 until i>j; 52 if l<j then sort1(l,j); 53 if i<r then sort1(i,r); 54 end; 55 56 procedure sort2(l,r:longint); 57 var i,j,x,y: longint; 58 begin 59 i:=l; 60 j:=r; 61 x:=b[(l+r) div 2]; 62 repeat 63 while b[i]<x do inc(i); 64 while x<b[j] do dec(j); 65 if not(i>j) then 66 begin 67 swap(b[i],b[j]); 68 inc(i); 69 j:=j-1; 70 end; 71 until i>j; 72 if l<j then sort2(l,j); 73 if i<r then sort2(i,r); 74 end; 75 76 procedure build(i,l,r:longint); 77 var m:longint; 78 begin 79 if l=r then 80 tree[i]:=sg[l] 81 else begin 82 tree[i]:=inf; 83 m:=(l+r) shr 1; 84 build(i*2,l,m); 85 build(i*2+1,m+1,r); 86 end; 87 end; 88 89 procedure push(i:longint); 90 begin 91 tree[i*2]:=min(tree[i*2],tree[i]); 92 tree[i*2+1]:=min(tree[i*2+1],tree[i]); 93 tree[i]:=inf; 94 end; 95 96 procedure work(i,l,r,x,y,z:longint); 97 var m:longint; 98 begin 99 if (x<=l) and (y>=r) then 100 tree[i]:=min(tree[i],z) 101 else begin 102 if tree[i]<>inf then push(i); 103 m:=(l+r) shr 1; 104 if x<=m then work(i*2,l,m,x,y,z); 105 if y>m then work(i*2+1,m+1,r,x,y,z); 106 end; 107 end; 108 109 function ask(i,l,r,x:longint):longint; 110 var m:longint; 111 begin 112 if l=r then exit(tree[i]) 113 else begin 114 if tree[i]<>inf then push(i); 115 m:=(l+r) shr 1; 116 if x<=m then exit(ask(i*2,l,m,x)) 117 else exit(ask(i*2+1,m+1,r,x)); 118 end; 119 end; 120 121 begin 122 readln(n,m); 123 for i:=1 to n do 124 begin 125 read(a[i]); 126 b[i]:=a[i]; 127 end; 128 sort2(1,n); 129 if b[1]<>0 then 130 begin 131 inc(t); 132 d[1]:=0; 133 end; 134 inc(t); 135 d[t]:=b[1]; 136 for i:=2 to n do 137 begin 138 if b[i]=b[i-1] then continue; 139 if b[i]-b[i-1]>1 then 140 begin 141 inc(t); 142 d[t]:=b[i-1]+1; 143 end; 144 inc(t); 145 d[t]:=b[i]; 146 end; 147 inc(t); 148 d[t]:=b[n]+1; 149 k:=1; 150 for i:=1 to n do 151 begin 152 loc[i]:=find(a[i]); 153 v[loc[i]]:=true; 154 while v[k] do inc(k); 155 sg[i]:=k; 156 end; 157 fillchar(last,sizeof(last),255); 158 fillchar(next,sizeof(next),255); 159 for i:=n downto 1 do 160 begin 161 next[i]:=last[loc[i]]; 162 last[loc[i]]:=i; 163 end; 164 165 build(1,1,n); 166 for i:=1 to m do 167 begin 168 readln(p[i],q[i]); 169 c[i]:=i; 170 end; 171 172 sort1(1,m); 173 j:=1; 174 for i:=1 to n do 175 begin 176 while p[j]=i do 177 begin 178 ans[c[j]]:=ask(1,1,n,q[j]); 179 inc(j); 180 end; 181 if next[i]=-1 then next[i]:=n+1; 182 work(1,1,n,i+1,next[i]-1,loc[i]); 183 end; 184 for i:=1 to m do 185 writeln(d[ans[i]]); 186 end.