原题网址:http://codeforces.com/contest/732/problem/E
从小到大枚举每个插座,将插座不断/2在hash表中找是否有与之匹配的(贪心思想)。这里hash表里相同元素还有不同标号,我将这些标号再拉一次链,复杂度上就有保证了(一开始相同元素直接丢一块没拉链就T了)。(拉链套拉链WA了好几发。。)
type
rec=record
v,i,next,first:longint;
end;
rec2=record
i,next:longint;
end;
const
MX=200050;
p=199999;
var
map:array[0..MX] of rec;
mp:array[0..MX] of rec2;
socket,num,used,match,real_used,first:array[0..MX] of longint;
n,m,i,f,now_used,tot_match,s,ss,t:longint;
tot_used:int64;
procedure swap(var a,b:longint);
var t:longint;
begin t:=a;a:=b;b:=t;end;
procedure sort(l,r:longint);
var
i,j,e:longint;
begin
i:=l;j:=r;e:=socket[(l+r)>>1];
repeat
while socket[i]<e do inc(i);
while e<socket[j] do dec(j);
if not (i>j) then
begin
swap(socket[i],socket[j]);
swap(num[i],num[j]);
inc(i);dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
procedure push(x,i:longint);
var
lab,t:longint;
begin
lab:=x mod p;
t:=first[lab];
while (t>0) do
begin
if (map[t].v=x) then
begin
inc(ss);mp[ss].i:=i;
mp[ss].next:=map[t].first;
map[t].first:=ss;
exit;
end;
t:=map[t].next;
end;
inc(s);map[s].v:=x;
map[s].next:=first[lab];first[lab]:=s;
inc(ss);mp[ss].i:=i;
mp[ss].next:=map[s].first;
map[s].first:=ss;
end;
function find(x:longint):longint;
var
lab,t,tt:longint;
begin
lab:=x mod p;
t:=first[lab];
while (t>0) do
begin
if (map[t].v=x) then
begin
tt:=map[t].first;
if (tt=0) then exit(-1);
map[t].first:=mp[tt].next;
exit(mp[tt].i);
end;
t:=map[t].next;
end;
exit(-1);
end;
begin
//assign(input,'E.in');reset(input);
//assign(output,'E.out');rewrite(output);
read(n,m);
for i:=1 to n do
begin
read(t);
push(t,i);
end;
for i:=1 to m do read(socket[i]);
for i:=1 to m do num[i]:=i;
sort(1,m);
for i:=1 to m do
begin
now_used:=0;used[i]:=-1;
while (used[i]=-1)and(socket[i]>1) do
begin
f:=find(socket[i]);
if (f<>-1) then
begin
used[i]:=now_used;
match[f]:=num[i];
inc(tot_match);
inc(tot_used,now_used);
end;
socket[i]:=socket[i]>>1+socket[i] and 1;
inc(now_used);
end;
if (used[i]<>-1) then continue;
f:=find(socket[i]);
if (f<>-1)
then
begin
used[i]:=now_used;
match[f]:=num[i];
inc(tot_match);
inc(tot_used,now_used);
end
else used[i]:=0;
end;
for i:=1 to m do real_used[num[i]]:=used[i];
writeln(tot_match,' ',tot_used);
for i:=1 to m-1 do
write(real_used[i],' ');
writeln(real_used[m]);
for i:=1 to n-1 do
write(match[i],' ');
writeln(match[n]);
//close(input);close(output);
end.