2017.07.11【NOIP提高组】模拟赛B组 进化序列(evolve) 题解

原题:

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.

你可能感兴趣的:(2017.07.11【NOIP提高组】模拟赛B组 进化序列(evolve) 题解)