简单题、
但如果用什么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;
有看不懂的……
程序:
{ 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.