很不错的hash
优化有两个方面:1.根据题目换一个更优化的算法 2.在算法运行过程中优化
这题除了暴力好像没别的办法了吧?
但是暴力也是有策略的!
到第i只牛特征为j的总数为sum[i,j];
找到最大的区间(l,r]使得sum[r,1]-sum[l,1]=sum[r,2]-sum[l,2]…=sum[r,k]-sum[l,k]
整理就得sum[r,1]-sum[r,2]=sum[l,1]-sum[l,2] sum[r,1]-sum[r,3]=sum[r,1]-sum[r,3]……
于是做到每只牛的时候,我们就能得到一个序列。满足条件就是两个序列相等,
怎么快速判断序列:hash!得解!
1 type link=^node; 2 node=record 3 data:longint; 4 next:link; 5 end; 6 const key=200007; 7 var hash:array[0..200010] of link; 8 sum:array[0..40] of longint; 9 num:array[0..100010,0..40] of longint; 10 ans,n,k,x,j,i,s:longint; 11 function max(a,b:longint):longint; 12 begin 13 if a>b then exit(a) else exit(b); 14 end; 15 16 function allsame(x,y:longint):boolean; //注意可能出现hash值相同但序列不同 17 var i:longint; 18 begin 19 allsame:=true; 20 for i:=1 to k do 21 if num[x,i]<>num[y,i] then exit(false); 22 end; 23 24 procedure add(x,y:longint); 25 var p:link; 26 begin 27 new(p); 28 p^.data:=y; 29 p^.next:=hash[x]; 30 hash[x]:=p; 31 end; 32 33 procedure push(x,i:longint); 34 var p:link; 35 begin 36 if hash[x]=nil then add(x,i) 37 else begin 38 p:=hash[x]; 39 while p<>nil do 40 begin 41 if allsame(p^.data,i) then 42 begin 43 ans:=max(ans,i-p^.data); //如果相同,那么当前序列就无需入hash 44 exit; 45 end; 46 p:=p^.next; 47 end; 48 add(x,i); //拉链法解决冲突 49 end; 50 end; 51 52 begin 53 readln(n,k); 54 add(0,0); 55 for i:=1 to n do 56 begin 57 readln(x); 58 j:=0; 59 while x<>0 do 60 begin 61 j:=j+1; 62 sum[j]:=sum[j]+x mod 2; 63 x:=x shr 1; 64 end; 65 s:=0; 66 for j:=1 to k do 67 begin 68 num[i,j]:=sum[1]-sum[j]; //生成序列 69 s:=(s+sqr(num[i,j])*j mod key) mod key ; //很奇怪的hash…… 70 end; 71 push(s,i); //hash值都不同那么序列一定不同 72 end; 73 writeln(ans); 74 end.
判断两个序列是否相同,hash是个好方法!