【BZOJ2081】Beads(哈希表)
题意:
翻转是指其中一段长度为k的子串全部翻转
n<=200000 a[i]<=n
思路:枚举k,直接哈希判充即可
时间复杂度是n/i求和,根据定理可得是O(n log n)级别的
单哈双哈都可能被卡,我用的是单哈+哈希表判重
1 const mo=250109; 2 var h1,h2,mi,c,a,head,vet,next:array[0..1000000]of longint; 3 n,i,p,j,st,ed,t1,t2,t3,l,ans,tot:longint; 4 5 function hash1(x,y:longint):longint; 6 begin 7 hash1:=(h1[y]-int64(h1[x-1])*mi[y-x+1] mod mo) mod mo; 8 hash1:=(hash1+mo) mod mo; 9 end; 10 11 function hash2(x,y:longint):longint; 12 begin 13 hash2:=(h2[y]-int64(h2[x-1])*mi[y-x+1] mod mo) mod mo; 14 hash2:=(hash2+mo) mod mo; 15 end; 16 17 procedure swap(var x,y:longint); 18 var t:longint; 19 begin 20 t:=x; x:=y; y:=t; 21 end; 22 23 procedure add(a,b:longint); 24 begin 25 inc(tot); 26 next[tot]:=head[a]; 27 vet[tot]:=b; 28 head[a]:=tot; 29 end; 30 31 function judge(u,x:longint):boolean; 32 var e,v:longint; 33 begin 34 e:=head[u]; 35 while e<>0 do 36 begin 37 v:=vet[e]; 38 if v=x then exit(false); 39 e:=next[e]; 40 end; 41 exit(true); 42 end; 43 44 begin 45 assign(input,'bzoj2081.in'); reset(input); 46 assign(output,'bzoj2081.out'); rewrite(output); 47 readln(n); 48 for i:=1 to n do read(a[i]); 49 mi[0]:=1; 50 for i:=1 to n do mi[i]:=int64(mi[i-1])*200291 mod mo; 51 for i:=1 to n do h1[i]:=(int64(h1[i-1])*200291+a[i]) mod mo; 52 for i:=1 to n div 2 do swap(a[i],a[n-i+1]); 53 for i:=1 to n do h2[i]:=(int64(h2[i-1])*200291+a[i]) mod mo; 54 for i:=1 to n do 55 begin 56 p:=0; tot:=0; 57 for j:=1 to n div i do 58 begin 59 st:=i*(j-1)+1; ed:=i*j; 60 t1:=hash1(st,ed); t2:=hash2(n-ed+1,n-st+1); 61 t3:=int64(t1)*t2 mod mo; 62 inc(t3); inc(t1); inc(t2); 63 if judge(t3,t1) then 64 begin 65 inc(p); 66 add(t3,t1); 67 add(t3,t2); 68 end; 69 end; 70 if p=ans then begin inc(l); c[l]:=i; end; 71 if p>ans then 72 begin 73 l:=1; c[1]:=i; ans:=p; 74 end; 75 for j:=1 to n div i do 76 begin 77 st:=i*(j-1)+1; ed:=i*j; 78 t1:=hash1(st,ed); t2:=hash2(n-ed+1,n-st+1); 79 t3:=int64(t1)*t2 mod mo; 80 inc(t3); 81 head[t3]:=0; 82 end; 83 end; 84 writeln(ans,' ',l); 85 for i:=1 to l-1 do write(c[i],' '); 86 write(c[l]); 87 close(input); 88 close(output); 89 end.
null