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 100007
using 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);
}