题目
题解思路
贪心 策略
将每个素数的首个二进制1累加,这样x的每个1都有可能异或出那个素数。
为什么呢,
首个二进制1保证了这个素数一定小于等于x。
由于这一位另一个数的这个位置肯定是0,并且在这个位置之前的1一定相同,另一个数只能通过调整之后的位数来让异或出来的数等于素数,但是素数首位还是0,所以异或出来的数肯定也小与x。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 5001000;
int prm[N] ;
int vis[N] ;
int cnt ;
int fp[N] ;
int a[N] ;
int ak[220] ;
void si()
{
vis[0] = 1 ;
vis[1] = 1 ;
for (int i = 2 ; i <= N -100 ; i++ )
{
if ( !vis[i] )
{
cnt++;
prm[cnt] = i ;
ak[(int)log2(i)]++;
for (int j = 2*i ; j <= N - 100 ; j+= i )
vis[j] = 1 ;
}
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
si();
int T ;
cin >> T ;
while ( T-- )
{
int x , ans = 0 ;
cin >> x ;
for (int i = 0 ; i < 21 ; i++ )
if ( x >> i & 1 )
ans += ak[i] ;
cout << ans << "\n" ;
}
return 0 ;
}