GFOJ686 序列操作

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.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值