题意
求[L,R]中,最小质因子大于K的数(包括素数)的异或和。
L,R<=1e14,K<=1e9
R-L<=1e7
就TM是个线筛
在线筛过程中,由于每个数N都会被他的最小质因子筛到。若不是质数,则其最小质因子必定 <=N−−√ <= N <script type="math/tex" id="MathJax-Element-141"><=\sqrt N</script>。
注意到当枚举的数>= N−−√ N 时,我们就可以将 N N <script type="math/tex" id="MathJax-Element-143">N</script>以内的合数全部标记出来了。
那么,我们线筛做到1e7的时候,[L,R]区间里的数如果被标记了(注意当i<=K时才标记),那说明其有K以内的质因子。
若没有被标记,则要么他是素数,要么是应该在[K+1,1e7]这一段区间里标记的数,也就是应该算进答案的数。
这题就没了。
实现
里面混了个没用的pollard rho,脑抽的时候打的。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#define abs(x) ((x) > 0 ? (x) : -(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int D = 1e7;
ll L,R,K;
ll ans;
ll p[700000], is[D + 10], ali[10000000 + 10];
ull seed = 998244353;
ull rnd() {
return rand() + rand() * RAND_MAX;
return seed = seed * 1000000007 ^ 233333333;
}
ll mul(ll x, ll y,ll mo) {
x%=mo,y%=mo;
ll z=(ld) x * y / mo;
z = x * y - z * mo;
if(z < 0) z += mo; else if(z > mo) z -= mo;
return z;
}
void init() {
for (int i = 2; i <= D; i ++) {
if (is[i] == 0) {
p[++p[0]] = i;
if (i <= K) {
ll st = L + i - L % i;
if (st - i >= L) st -= i;
if (st == i) st += i;
for (; st <= R; st += i) {
ali[st - L] = 1;
}
}
}
for (int j = 1; j <= p[0] && i * p[j] <= D; j++) {
is[i * p[j]] = 1;
if (i % p[j] == 0) break;
}
}
}
ll ksm(ll x,ll y,ll mo) {
ll ret = 1;
for (; y; y>>=1) {
if (y & 1) ret = mul(ret, x, mo);
x = mul(x, x, mo);
}
return ret;
}
ll f[100];
int mr(ull a,ll p) {
a%=p; if (a==0) return 1;
ll d = p - 1;
while ((d&1)==0) d>>=1;
ll x = ksm(a, d, p);
while (d < p - 1) {
ll nx = mul(x, x, p);
if (nx == 1) {
if (x != 1 && x != p - 1) return 0;
return 1;
}
x = nx; d *= 2;
}
return x == 1;
}
ll gcd(ll x,ll y) {
return y==0?x:gcd(y,x%y);
}
#define nex(x) (((x) * (x) + c) % a)
ll stop=0;
void pr(ll a) {
if (stop) return;
if (mr(2,a) && mr(3,a) && mr(61,a)) {
if (a < K) stop = 1;
f[++f[0]] = a;
return;
}
while (1) {
ll c = rnd() % a + 1;
ll x = c, y = nex(x);
while (x != y) {
ll g = gcd(abs(x - y), a);
if (g != a && g != 1) {
pr(a / g);
pr(g);
return;
}
x = nex(x), y = nex(nex(y));
}
}
}
int cnt;
int check(ll x) {
if (x <= D && is[x] == 0) return 1;
f[0] = 0; stop=0;
pr(x);
cnt++;
if (f[1]==x) return 1;
ll mi = 1e18;
for (int i = 1; i <= f[0]; i++)
mi = min(mi, f[i]);
if (mi > K) return 1; else return 0;
}
int main() {
freopen("prime.in","r",stdin);
// freopen("prime.out","w",stdout);
cin>>L>>R>>K;
init();
for (ll i = L; i <= R; i ++)
if (!ali[i - L]) {
ans ^= i;
}
cout<<ans<<endl;
}