简单题、
但如果用什么trie树 AC自动机貌似很复杂 不去想了、
有要研究的去Nocow上
算法是:
从头到尾扫一遍,记hash[i,j]表示字符转化为二进制数i ,长度为j位 有多少个这样的字符 哈希表、
比如"0010"出现了3次 那么hash[2,4]就等于3
因为最大2^12,*上2^5 并不大、
扫描整个哈希表,保存在g数组中
g[i,1] 记录出现频数 ,g[i,2]记录字符长度 ,g[i,3]记录转化为二进制数是多少
举个例子吧: 比如字符串"001011“在整个字符串中出现了24次
长度为6 所以g[i,2]=6
二进制数为11所以g[i,3]=11
频数 g[i,1]=24
快排 这里有三个关键字 按照第一第二第三关键字 排序
迎刃而解、、
这段代码很重要
x:
=
g[(l
+
r) div
2
,
1
];
p: = g[(l + r) div 2 , 2 ];
q: = g[(l + r) div 2 , 3 ];
repeat
while (g[i, 1 ] > x)or((g[i, 1 ] = x)and(g[i, 2 ] < p))or((g[i, 1 ] = x)and(g[i, 2 ] = p)and(g[i, 3 ] < q)) do
inc(i);
while (x > g[j, 1 ])or((x = g[j, 1 ])and(p < g[j, 2 ]))or((g[j, 1 ] = x)and(p = g[j, 2 ])and(q < g[j, 3 ])) do
dec(j);
if not(i > j) then
begin
y: = g[i];
g[i]: = g[j];
g[j]: = y;
inc(i);
j: = j - 1 ;
end;
p: = g[(l + r) div 2 , 2 ];
q: = g[(l + r) div 2 , 3 ];
repeat
while (g[i, 1 ] > x)or((g[i, 1 ] = x)and(g[i, 2 ] < p))or((g[i, 1 ] = x)and(g[i, 2 ] = p)and(g[i, 3 ] < q)) do
inc(i);
while (x > g[j, 1 ])or((x = g[j, 1 ])and(p < g[j, 2 ]))or((g[j, 1 ] = x)and(p = g[j, 2 ])and(q < g[j, 3 ])) do
dec(j);
if not(i > j) then
begin
y: = g[i];
g[i]: = g[j];
g[j]: = y;
inc(i);
j: = j - 1 ;
end;
有看不懂的……
程序:
{
ID: xiaweiy1
PROG: contact
LANG: PASCAL
}
const two:array[0..14]of longint=(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384);
maxn=300000;
type rec=array[1..3]of longint;
var a,b,n,tot,i,j,k,t,done,tmp,total,now:longint;
hash:array[0..4097,1..13]of longint;
f:array[1..maxn]of char;
s:string;
g:array[1..maxn]of rec;
tt:char;
function calc(st,en:longint):longint;
var sum,i,res:longint;
begin
sum:=-1;
res:=0;
for i:=en downto st do
begin
inc(sum);
res:=res+two[sum]*(ord(f[i])-ord('0'));
end;
exit(res);
end;
procedure sort(l,r: longint);
var
i,j,x,p,q: longint;
y:rec;
begin
i:=l;
j:=r;
x:=g[(l+r) div 2,1];
p:=g[(l+r) div 2,2];
q:=g[(l+r) div 2,3];
repeat
while (g[i,1]>x)or((g[i,1]=x)and(g[i,2]<p))or((g[i,1]=x)and(g[i,2]=p)and(g[i,3]<q)) do
inc(i);
while (x>g[j,1])or((x=g[j,1])and(p<g[j,2]))or((g[j,1]=x)and(p=g[j,2])and(q<g[j,3])) do
dec(j);
if not(i>j) then
begin
y:=g[i];
g[i]:=g[j];
g[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function getit(len,x:longint):string;
var t,p,i:longint;
s:string;
begin
s:='';
p:=x;
while p>1 do
begin
t:=p mod 2;
s:=char(t+48)+s;
p:=p div 2;
end;
if p=1 then s:='1'+s;
for i:=1 to len-length(s) do s:='0'+s;
exit(s);
end;
begin
assign(input,'contact.in');
reset(input);
assign(output,'contact.out');
rewrite(output);
readln(a,b,n);
while not eof do
begin
read(tt);
if (ord(tt)=48)or(ord(tt)=49) then
begin
inc(tot);
f[tot]:=tt;
end;
end;
for i:=1 to tot+1-a do
begin
for j:=a to b do
begin
t:=i+j-1;
if t<=tot then
begin
tmp:=calc(i,t);
inc(hash[tmp,j]);
end;
end;
end;
total:=0;
for i:=0 to two[b] do
begin
for j:=a to b do
begin
if hash[i,j]<>0 then
begin
inc(total);
g[total,1]:=hash[i,j]; //frequency
g[total,2]:=j; //length
g[total,3]:=i; //number
end;
end;
end;
sort(1,total);
done:=0;
i:=1;
while i<=total do
begin
tmp:=g[i,1];
j:=i;
while (j+1<=total)and(g[j+1,1]=tmp)do inc(j);
writeln(tmp);
now:=0;
for k:=i to j do
begin
inc(now);
s:=getit(g[k,2],g[k,3]);
if now mod 6=0 then
begin
write(s);
if k<>j then writeln;
end
else
begin
if k<>j then write(s,' ') else write(s);
end;
end;
writeln;
inc(done);
if done=n then break;
i:=j+1;
end;
close(input);
close(output);
end.