jzoj3518【NOIP2013模拟11.6A组】进化序列

来源:互联网 发布:linux ntp 开机启动 编辑:程序博客网 时间:2024/05/30 23:44

3518. 【NOIP2013模拟11.6A组】进化序列

Description

Abathur采集了一系列Primal Zerg 的基因样本,这些基因构成了一个完整的进化链。为了方便,我们用A0,A1…An-1 这n 个正整数描述它们。

一个基因Ax 可以进化为序列中在它之后的基因Ay。这个进化的复杂度,等于Ax | Ax+1…| Ay的值,其中| 是二进制或运算。

Abathur 认为复杂度小于M 的进化的被认为是温和的。它希望计算出温和的进化的对数。

Input

第一行包含两个整数n,m。

接下来一行包含A0,A1…An-1 这n 个正整数,描述这n 个基因。

Output

第一行包含一个整数,表示温和的进化的对数。

分析:设头指针i和尾指针j,每次或第j个数,如果大于等于m,ans+=j-i-1,并把第i个数“减”掉,i后移一位。

代码

#include <cstdio>#define maxn 100007using namespace std;int a[maxn][35],m[35],f[35];bool fl[35];int num,n,x;long long ans;void changem(int x){    int p=1;    while (x>0)    {        m[p]=x%2;        x/=2;        p++;    }}void change(int x,int i){    int p=1;    while (x>0)    {        a[i][p]=x%2;        x/=2;        p++;    }}void add(int x){    for (int i=1;i<=32;i++)    if (a[x][i]==1)     {        f[i]++;    }}bool check(){    for (int i=32;i>=1;i--)    {        if (f[i]==0&&m[i]==1) return true;        if (f[i]>0&&m[i]==0) return false;    }    return false;}void sub(int x){    for (int i=1;i<=32;i++)        if (a[x][i]==1) f[i]--;}int main(){    freopen("evolve.in","r",stdin);    freopen("evolve.out","w",stdout);    scanf("%d%d",&n,&x);    changem(x);    for (int i=1;i<=n;i++)    {        scanf("%d",&x);        change(x,i);    }    int i=1,j=1;    while (j<=n)    {        add(j);        while (check())         {            if (j>=n) break;            j++;            add(j);         }        if (!check())         {            sub(j);            sub(i);            ans+=j-i-1;            i++;            j--;        }           j++;    }    for (int k=i;k<=n;k++)        ans+=n-k;    printf("%lld",ans);    fclose(stdin);fclose(stdout);}
阅读全文
0 0
原创粉丝点击