【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.

 

posted on 2017-04-15 09:48  myx12345  阅读(203)  评论(0编辑  收藏  举报

导航