题意
有两个要求: 1.求某个区间的质数的个数; 2.先求出由该区间内质数组成的数组,然后求该数组有多少个子区间使得子区间内的数AND和为0;
分析
因为题目给的时间为2秒(对于c++来说),所以可以预先筛选出1~1e8内的质数,这样就可以求出某段区间的质数数组以及质数个数了;其次求子区间个数,我们发现质数除了2以外都是奇数,也就意味着它们的最低位都是1,显然如果质数数组没有2的话,其他质数的AND和不可能为0;对于有2的情况,可以直接枚举质数数组,从前往后求AND和,如果在在下标i的AND和为0,那么i后面的AND和一定为0,因为0AND任何数都为0,所以子区间个数就为k-i(k为质数数组的长度)。
c++代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<iomanip>
#include<unordered_set>
#include<queue>
#include<cmath>
#include<stack>
#define FI(x) fixed<<setprecision(x)
using namespace std;
const int N = 100000010,M=10000010;
int prim[N];
bool st[N];
int cot;
void init()
{
for(int i=2;i<=N;i++)
{
if(!st[i])
prim[cot++]=i;
for(int j=0;prim[j]<=N/i;j++)
{
st[prim[j]*i]=true;
if(i%prim[j]==0)
break;
}
}
}
int main()
{
init();
int t;
cin>>t;
while(t--)
{
int x,y;
cin>>x>>y;
// vector<int> A;
int b[N];
int k=0;
for(int i=0;i<cot;i++)
{
if(prim[i]>=x&&prim[i]<=y)
{
//A.push_back(prim[i]);
b[k++]=prim[i];
}
else if(prim[i]>y)
break;
}
cout<<k<<" ";
if(k==0)
{
cout<<0<<'\n';
continue;
}
if(b[0]!=2)
{
cout<<0<<'\n';
continue;
}
int m=0;
int u=b[0];
for(int i=1;i<k;i++)
{
u&=b[i];
if(u==0)
{
m=k-i;
break;
}
}
cout<<m<<'\n';
}
return 0;
}