jzoj100047. 基因变异
题目描述
21 世纪是生物学的世纪,以遗传与进化为代表的现代生物理论越来越多的 进入了我们的视野。 如同大家所熟知的,基因是遗传因子,它记录了生命的基本构造和性能。 因此生物进化与基因的变异息息相关,考察基因变异的途径对研究生物学有着 至关重要的作用。现在,让我们来看这样一个模型:
1、所有的基因都可以看作一个整数或该整数对应的二进制码;
2、在 1 单位时间内,基因 x 可能会在其某一个二进制位上发生反转;
3、在 1 单位时间内,基因 x 可能会遭到可感染基因库内任一基因 y 的影响 而突变为 x XOR y。
现在给出可感染基因库,Q 组询问,每组给出初始基因与终止基因,请你 分别计算出每种变异最少要花费多少个单位时间。
输入
第 1 行两个整数 N, Q; 第 2 行 N 个用空格隔开的整数分别表示可感染基因库内的基因; 接下来 Q 行每行两个整数 S、T,分别表示初始基因与终止基因。
输出
输出 Q 行,依次表示每组初始基因到终止基因间最少所花时间。
样例
输入
3 3
1 2 3
3 4
1 2
3 9
输出
3 3
1 2 3
3 4
1 2
3 9
题解
由于x xor x=0
所以x xor (x xor y)=y
所以我们只需求出从0变成x xor y的代价,即可算出从x变成y的代价。
而且因为起点相同,只需求出0的即可。
由于将第i位反转相当于xor 2的i次方,
所以我们将2的1~20次方加入基因库
以0为起点bfs一遍,f[g]+1 ——>f[g xor a[i]] (g<=1000000)
输出f[x xor y]即可。
标:
var
i,j,n,q,x,y,l,r:longint;
f:array[0..1048575]of longint;
a:array[1..41]of longint;
dl:array[1..10000000]of longint;
bz:array[0..1048575]of boolean;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
begin
readln(n,q);
for i:=1 to n do read(a[i]);
a[n+1]:=1;
for i:=n+2 to n+20 do a[i]:=a[i-1]*2;
n:=n+20;
fillchar(f,sizeof(f),100);
f[0]:=0;
dl[1]:=0;
l:=1;
r:=1;
while l<=r do
begin
for i:=1 to n do
begin
if f[dl[l]]+1<f[dl[l] xor a[i]] then
begin
f[dl[l]xor a[i]]:=f[dl[l]]+1;
if bz[dl[l] xor a[i]]=false then
begin
bz[dl[l]xor a[i]]:=true;
inc(r);
dl[r]:=dl[l] xor a[i];
end;
end;
end;
bz[dl[l]]:=false;
inc(l);
end;
for i:=1 to q do
begin
readln(x,y);
writeln(f[x xor y]);
end;
end.
很简单吧