Description
Solution
这是今天最签到的一题,死于捆绑测试
考虑区间筛。我们预处理
min(k,r√)
m
i
n
(
k
,
r
)
的质数,然后用这些质数筛出区间[l,r]内的类质数
然后就做完了
这个杯具告诉我们可以暴力和正解一起交,这样正解挂了还可以有暴力分qaq
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define rep(i,st,ed) for (register LL i=st,_=ed;i<=ed;++i)
typedef long long LL;
const int MOD=44775803;
const int N=10000005;
LL prime[N],hash[MOD+5];
bool not_prime[N],rec[MOD+5];
__attribute__((optimize("O2")))
inline int get_hash(LL x) {
int i=x%MOD;
for (;hash[i]&&hash[i]!=x;i=i%MOD+1);
return i;
}
__attribute__((optimize("O2")))
inline void pre_work(LL n,LL l,LL r,LL k) {
rep(i,2,n) {
if (!not_prime[i]) {
prime[++prime[0]]=i;
}
for (int j=1;j<=prime[0]&&prime[j]<=k&&i*prime[j]<=n;j++) {
not_prime[i*prime[j]]=1;
if (i%prime[j]==0) break;
}
}
l=std:: max(l,n-1);
rep(i,1,prime[0]) if (prime[i]<=k) {
LL st=(l-1)/prime[i]+1;
LL ed=r/prime[i];
rep(j,st,ed) {
LL tmp=prime[i]*j;
int pos=get_hash(tmp);
if (hash[pos]==0) {
hash[pos]=tmp;
rec[pos]=1;
}
// printf("%lld\n", prime[i]*j);
}
}
}
bool is_prime(LL x,LL k) {
for (int i=1;prime[i]<=k&&prime[i]*prime[i]<=x&&i<=prime[0];i++) {
if (x%prime[i]==0) return false;
}
return true;
}
__attribute__((optimize("O2")))
int main(void) {
freopen("prime.in","r",stdin);
freopen("prime.out","w",stdout);
LL l,r,k,ans=0; scanf("%lld%lld%lld",&l,&r,&k);
if (r<=10000000) {
pre_work(r,l,r,k);
rep(i,l,r) if (!not_prime[i]) {
ans^=i;
}
printf("%lld\n", ans);
return 0;
}
pre_work(1+sqrt(r),l,r,k);
rep(i,l,r) {
int pos=get_hash(i);
if (!hash[pos]||!rec[pos]||hash[pos]!=i) {
ans^=i;
}
}
printf("%lld\n", ans);
return 0;
}