3 3
1 2 3 4 5 6
1 2 3 0 0 0
0 0 0 4 5 6
题解:
一脸容斥的样子。
枚举判断是否相同的泉水集合S,若|S|>=K,则inc(ANS,(-1)^(|S|-K+1)*C(|S|,K)*相同对数)。
用哈希表记录、判断(我之前竟然写了类似字符串哈希的的做法,哈希值相同直接判断相同,WA惨了)。
代码:
var i,j,k,l,n,m:longint; f:array[0..200001,1..6]of int64; b:array[1..6]of longint; c:array[0..6,0..6]of int64; cc:array[0..133330]of longint; d:array[0..200001,-1..6]of longint; a:array[0..200001]of int64; ans:int64; procedure find(x,z:longint;y:int64); var i,j,l:longint; begin i:=cc[a[z]]; while i>0 do begin l:=0; for j:=1 to x do if d[i,j]<>f[z,b[j]] then begin l:=1; break; end; if l=0 then begin ans:=ans+y*d[i,0]; inc(d[i,0]); exit; end; i:=d[i,-1]; end; inc(m); for i:=1 to x do d[m,i]:=f[z,b[i]]; d[m,0]:=1; d[m,-1]:=cc[a[z]]; cc[a[z]]:=m; end; function ss2(x:longint;y:int64):int64; var i,j,k:longint; begin ss2:=0; m:=0; for i:=0 to 133330 do cc[i]:=0; for i:=1 to n do begin a[i]:=1; for j:=1 to x do a[i]:=(a[i]*13131+f[i,b[j]])mod 133331; find(x,i,y); end; end; procedure ss(x,y:longint); var i:longint; begin if x>6 then begin if y>=k then begin if(y-k)mod 2=0 then ss2(y,c[y,k]) else ss2(y,-c[y,k]); end; exit; end; ss(x+1,y); inc(y); b[y]:=x; ss(x+1,y); end; begin c[0,0]:=1; for i:=1 to 6 do begin c[i,0]:=1; c[i,i]:=1; for j:=1 to i-1 do c[i,j]:=c[i-1,j-1]+c[i-1,j]; end; readln(n,k); for i:=1 to n do for j:=1 to 6 do read(f[i,j]); ss(1,0); writeln(ans); end.
原文:http://www.cnblogs.com/GhostReach/p/6259899.html