505 区间筛

// 505 区间筛.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*

http://oj.daimayuan.top/course/21/problem/521


给两个数字l,r,求l∼r中的所有素数p。

为了防止输出过大和防止打表,给定a,b,输出这些素数(a⋅p+b)mod2^32的异或和。

输入格式
第一行四个整数l,r,a,b。

输出格式
一个整数,表示答案。

样例输入
1 100 1 0
样例输出
64
数据规模
对于所有数据,保证1≤l≤r≤10^14,0≤a,b<2^32,r−l≤10^7。
*/

#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

int primes[670000], cnt;
bool st[10000010];

long long l, r, a, b;

void getprimes(int x) {
    for (int i = 2; i <= x; i++)
    {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] <= x / i; j++)
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int main()
{
	cin >> l >> r >> a >> b;
	getprimes(sqrt(r) + 1);
    memset(st, 0, sizeof st);

    for (int i = 0; i < cnt; i++) {
        long long p = primes[i];
        //从l开始将倍数置0;
        long long start = max(l + p - (l % p), 2ll * p);
        if (l % p == 0) start = l;
        for (long long j = start; j <= r; j += p) {
            st[j - l] = 1;
        }
    }
    if (l == 1) st[0] = 1;
    long long ans = 0;
    for (int i = 0; i < r - l + 1; i++) {
        if (st[i] != 1) {
            long long p = i + l;
            ans ^= (unsigned int)(a * p + b);
            ans = (unsigned int)ans;
        }
    }

    cout << ans << endl;
	return 0;
}

posted on 2025-01-21 15:41  itdef  阅读(17)  评论(0)    收藏  举报

导航