dls的数论-线性筛,整数分块,longlong取mod

线性筛

p[i]:表示i的最小素因子的是i,pr[]里面放的是素数是哪些
第二层循环,循环pr[j], 当循环到i的最小素因子的时候就会跳出来,每个数也都是在他的最小素因子的地方被筛掉的
#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 5e7+10;
int pr[N/5], pj[N], tot; 

int main(){
    int n; unsigned int a, b;
    scanf("%d %u %u", &n, &a, &b);
    // cin >> n >> a >> b;
    unsigned int ans = 0;
    pj[1] = 1;
    for(unsigned int i = 2; i <= n; i++){
        if(!pj[i]) pj[i] = i, pr[++tot] = i, ans ^= (a * i + b);
        for(int j = 1; j <= tot && pr[j] <= n / i; j ++){
            pj[pr[j] * i] = pr[j];
            if(pr[j] == pj[i]) break;
        }
    }    
    // cout << ans << endl;
    printf("%u\n", ans);
    return 0;
}

整数分块

n/1,n/2....n/n向下取整一共有根号n种取值
对2^k取mod相当于随便溢出,最后取一次mod就可以了
#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef unsigned long long ull;
ull n, sum;

int main(){
    scanf("%llu", &n);
    for(ull l = 1; l <= n; l ++){
        ull d = n / l; ull r = n / d;
        sum += (n - l * d + n - r * d) * (r - l + 1) / 2;
        l = r;
    }
    printf("%llu\n", sum % (1ull << 60));
    return 0;
}

a,b, m都是18次方级别的,用int128比较慢
LL mul(LL x, LL y, LL m){
    x %= m; y %= m;
    LL d = ((long double)x * y / m);
    d = x * y - d * m;
    if(d >= m) d -= m;
    if(d < 0) d += m;
    return d;
}
posted @ 2022-03-20 12:01  牛佳文  阅读(66)  评论(0编辑  收藏  举报