\end{aligned} 若大于1的整数n不是任意两个大于1的整数的异或积,则称之为异或质数。上面的例子说明9不是一个异或质数。类似地,5 = 3 \otimes 3也不是一个异或质数。较小的异或质数包括2, 3, 7, 11, 13, …,而第10个异或质数是41。 求第5\ 000\ 000个异或质数。 i64 lim=1e8; inline long long xor_mul(long long a, long long b) { long long res = 0; while (b > 0) { if (b & 1) res ^= a; a <<= 1; b >>= 1; } return res; }
long long n,m,res; char vis[100000010];//存最小质因数,负的表示质数表中的位置(负的) void sieve(int n){//[1,n] int tmp; for(int i=2;i<=n;++i){ if(vis[i]==0)res++; int cnt=0; for(int j=2;;++j){ i64 tmp=xor_mul(i,j); if(tmp>=n){ cnt++; if(cnt>10)break; }else vis[tmp]=1; } if(i%1000==0){ fout<<"! "<<i<<"\n"; fout.flush(); } } int rres=0; for(int i=2;i<=n;++i){ if(vis[i]==0){ rres++; if(rres==5000000){ fout<<"! "<<i<<"\n"; } } } fout<<res<<"\n"; }
inline i64 xor_mul(i64 a, i64 b) { i64 res = 0; while (b > 0) { if (b & 1) res ^= a; a <<= 1; b >>= 1; } return res; }
// 获取最高位 (Degree) inline int get_deg(i64 n) { if (n == 0) return -1; return 63 - __builtin_clzll(n); }
void solve() { vis.resize(MAXN + 1, false); int target = 5000000; int limit_deg = get_deg(MAXN);
// 异或积筛法:类似埃氏筛 // 注意:只需遍历到 deg(i) <= limit_deg / 2 即可 for (i64 i = 2; (get_deg(i) * 2) <= limit_deg; ++i) { if (vis[i]) continue; // 只有异或质数才需要去筛别人
int deg_i = get_deg(i); // j 从 i 开始,避免重复(异或积满足交换律) for (i64 j = i; ; ++j) { int deg_j = get_deg(j); // 核心优化:利用 deg(i \otimes j) = deg(i) + deg(j) if (deg_i + deg_j > limit_deg) break; i64 res = xor_mul(i, j); if (res <= MAXN) { vis[res] = true; } } }
// 统计第 5,000,000 个 int count = 0; for (int i = 2; i <= MAXN; ++i) { if (!vis[i]) { count++; if (count == target) { cout << "The 5,000,000th XOR Prime is: " << i << endl; return; } } } }