bzoj3339 bzoj3585

两题本质是一样,只不过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.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473088.html