• 数论题单


    我发现kuangbin题单里的数论好像有点水,都是些线筛之类的

    杜教筛

    洛谷模板(杜教筛)

    #include<bits/stdc++.h>
    #include<unordered_map>
    using namespace std;
    
    template<typename T>void read(T& x) {
    	x = 0;
    	int p = 1;
    	char c = getchar();	
    	while (!isdigit(c)) { if (c == '-')p = -1, c = getchar(); }
    	while (isdigit(c)) { x = (x << 1) + (x << 3) + (c - 48); c = getchar(); }
    	x *= p;
    }
    
    template<typename T>void write(T x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    typedef long long ll;
    const int maxn = 6e6 + 10;
    int mu[maxn];
    ll phi[maxn];
    int sum_mu[maxn];
    ll sum_phi[maxn];
    int vis[maxn];
    int prime[maxn], cnt;
    unordered_map<int, ll>MU, PHI;
    
    void get(int N) {
    	phi[1] = mu[1] = 1;
    	for (int i = 2; i <= N; i++) {
    		if (!vis[i]) {
    			prime[++cnt] = i;
    			mu[i] = -1;
    			phi[i] = i - 1;
    		}
    		for (int j = 1; j <= cnt && prime[j] * i <= N; j++) {
    			vis[prime[j] * i] = 1;
    			if (i % prime[j] == 0) {
    				phi[i * prime[j]] = phi[i] * prime[j];
    				break;
    			}
    			else {
    				mu[i * prime[j]] = mu[i] * -1;
    				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
    			}
    		}
    	}
    	for (int i = 1; i <= N; i++) {
    		sum_phi[i] = sum_phi[i - 1] + phi[i];
    		sum_mu[i] = sum_mu[i - 1] + mu[i];
    	}
    }
    ll djs_mu(ll x) {
    	if (x <= maxn - 10)return sum_mu[x];
    	if (MU.count(x) != 0)return MU[x];
    	int ans = 1;
    	for (int l = 2, r;l <= x; l = r + 1) {
    		r = x / (x / l);
    		ans -= (r - l + 1) * djs_mu(x / l);
    	}
    	return MU[x] = ans;
    }
    
    ll djs_phi(ll x) {
    	if (x <= maxn - 10)return sum_phi[x];
    	if (PHI.count(x) != 0)return PHI[x];
    	ll ans = x * (x + 1) / 2;
    	for (ll l = 2, r; l <= x; l = r + 1) {
    		r = x / (x / l);
    		ans -= (r - l + 1) * djs_phi(x / l);
    	}
    	return PHI[x] = ans;
    }
    
    int main() {
    	int t, n;
    	read(t);
    	get(maxn - 10);
    	while (t--) {
    		read(n);
    		write(djs_phi(n)); putchar(' ');
    		write(djs_mu(n)); puts("");
    	}
    }
    

    莫比乌斯反演

    约数和

    YY的GCD

    P3455 [POI2007]ZAP-Queries

    [sum_{i=1}^nsum_{j=1}^m[gcd(i,j)=1] ]

    [ o sum_{i=1}^nsum_{j=1}^msum_{d|gcd(i,j)}mu(d) ]

    [ o sum_{d=1}^nmu(d)*lfloor dfrac nd floor * lfloor dfrac md floor ]

    分块搞就完事了

    for (int l = 1, r; l <= min(n, m); l = r + 1) {
    			r = min(n / (n / l), m / (m / l));
    			ans += (n / l) * (m / l) * (sum[r] - sum[l - 1]);
    }
    

    [sum_{i=1}^nsum_{j=1}^m[gcd(i,j)=k] ]

    [sum_{i=1}^{lfloor frac nk floor}sum_{j=1}^{lfloor frac mk floor}[gcd(i,j) = 1] ]

    题目链接

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5 + 10;
    int vis[maxn], prime[maxn], cnt, mu[maxn], sum[maxn];
    
    void get_mu() {
    	mu[1] = 1;
    	for (int i = 2; i < maxn; i++) {
    		if (!vis[i]) {
    			prime[++cnt] = i;
    			mu[i] = -1;
    		}
    		for (int j = 1; j <= cnt && prime[j] * i < maxn; j++) {
    			vis[prime[j] * i] = 1;
    			if (i % prime[j] == 0) break;
    			mu[prime[j] * i] = mu[i] * -1;
    		}
    	}
    	for (int i = 1; i < maxn; i++) sum[i] = sum[i - 1] + mu[i];
    }
    
    int T, n, m, k;
    int main() {
    	scanf("%d", &T);
    	get_mu();
    
    	while (T--) {
    		scanf("%d%d%d", &n, &m, &k);
    		n /= k; m /= k;
    		long long ans = 0;
    		for (int l = 1, r; l <= min(n, m); l = r + 1) {
    			r = min(n / (n / l), m / (m / l));
    			//这里没有加long long转换wa了一次
    			ans += 1ll* (n / l) * (m / l) * (sum[r] - sum[l - 1]);
    		}
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    通信接收机同步模块
    CAZAC序列
    Verilog Tricks
    载波同步
    Matlab step方法
    CRC校验码
    比特冗余
    Vivado RAM使用
    collection
    hashlib
  • 原文地址:https://www.cnblogs.com/sduwh/p/13708433.html
Copyright © 2020-2023  润新知