原题:
http://172.16.0.132/senior/#contest/show/2050/2
题目描述:
Abathur采集了一系列Primal Zerg 的基因样本,这些基因构成了一个完整的进化链。为了方便,我们用A0,A1...An-1 这n 个正整数描述它们。
一个基因Ax 可以进化为序列中在它之后的基因Ay。这个进化的复杂度,等于Ax | Ax+1...| Ay的值,其中| 是二进制或运算。
Abathur 认为复杂度小于M 的进化的被认为是温和的。它希望计算出温和的进化的对数。
输入:
第一行包含两个整数n,m。
接下来一行包含A0,A1...An-1 这n 个正整数,描述这n 个基因。
输出:
第一行包含一个整数,表示温和的进化的对数。
样例输入:
4 6
1 3 5 1
样例输出:
2
数据范围限制:
对于30% 的数据,1 <= n <=1000。
对于100% 的数据,1 <= n<= 100000,0 <= m <= 2^30,1<= Ai<= 2^30。
分析:
前缀和+暴力枚举+优化
优化:由于数据太大,我们可以跳着做,当发现跳到的点不符合要求,那么返回上一个点,从这个点开始一个一个找,ans+=(r-l+1);
实现:
var
ans,p:int64;
n,m,i,j,t,l:longint;
a,s:array[1..100000]of int64;
procedure w;
begin
for i:=1 to n do
begin
p:=0;
t:=i;
if i+100<=n then
while true do
begin
if p or s[t]>m then break;
p:=p or s[t];
t:=t+101;
if t+100>n then break;
end;
if t>i then ans:=ans+t-1-i;
l:=0;
for j:=t to n do
begin
if p or a[j]>m then break;
inc(l);
p:=p or a[j];
end;
if l>0 then
if t=i then ans:=ans+l-1
else ans:=ans+l;
end;
end;
begin
assign(input,'evolve.in');reset(input);
assign(output,'evolve.out');rewrite(output);
readln(n,m);
for i:=1 to n do read(a[i]);
s:=a;
for i:=1 to n do
for j:=i+1 to i+100 do s[i]:=s[i] or a[j];
w;
writeln(ans);
end.