CJJ被SCOI2012那道序列操作做吐了,于是他想出了一道简单的序列操作的题目自我安慰。
有一个包含n个数序列的Ai,她想找出两个非空的集合S、T。
这两个集合要满足以下的条件:
1、两个集合中的元素都为整数,且都在[1,n] 里,即Si,Ti∈[1,n]。
2、对于集合S中任意一个元素x,集合T中任意一个元素y,满足x < y。
3、对于大小分别为p, q的集合S与T,满足:
A[s1] xor A[s2] xor A[s3] ... xor A[sp] =
A[t1] and A[t2] and A[t3] ... and A[tq]
上式中的xor和and分别表示位运算异或运算和与运算。
CJJ想知道一共有多少对这样的集合(S,T),既然你都来了,就帮忙一起算一下吧。
源代码
const
mo=100000000;
type
arr=array[0..40] of longint;
var
n,i,j,p,q:longint;
st:string;
a:array[1..1000] of longint;
f:array[0..1,0..1023,1..2,0..40] of longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure plus(var x:arr;y:arr);
var
i:longint;
begin
for i:=1 to max(x[0],y[0]) do begin
x[i]:=x[i]+y[i];
x[i+1]:=x[i+1]+x[i] div mo;
x[i]:=x[i] mod mo;
end;
x[0]:=max(x[0],y[0]);
if x[x[0]+1]>0 then inc(x[0]);
end;
begin
readln(n);
for i:=1 to n do read(a[i]);
for i:=n downto 1 do begin
p:=i mod 2; q:=(i+1) mod 2;
f[p][a[i]][1][0]:=1;
f[p][a[i]][1][1]:=1;
for j:=0 to 1023 do begin
plus(f[p][j][1],f[q][j][1]);
plus(f[p][j and a[i]][1],f[q][j][1]);
plus(f[p][j][2],f[q][j][2]);
plus(f[p][j xor a[i]][2],f[q][j][2]);
plus(f[p][j xor a[i]][2],f[q][j][1]);
end;
fillchar(f[q],sizeof(f[q]),0);
end;
for i:=f[1][0][2][0] downto 1 do begin
str(f[1][0][2][i],st);
if i<>f[1][0][2][0] then for j:=1 to 8-length(st) do st:='0'+st;
write(st);
end;
if f[1][0][2][0]=0 then writeln(0);
end.