• 【模板】杜教筛(Sum)


    \(\text{Code}\)

    #include<cstdio>
    #include<tr1/unordered_map>
    #define LL long long
    using namespace std;
    const int M = 5e6;
    int vis[M + 5],p[M + 5],tot,T,n;
    LL phi[M + 1],mu[M + 1];
    
    tr1::unordered_map<int,LL> fm,fp;
    void init()
    {
    	mu[1] = phi[1] = 1LL;
    	for (int i = 2; i <= M; i++)
    	{
    		if (!vis[i]) p[++tot] = i,mu[i] = -1,phi[i] = i - 1;
    		for (int j = 1; j <= tot && p[j] * i <= M; j++)
    		{
    			vis[p[j] * i] = 1;
    			if (i % p[j] == 0) {phi[i * p[j]] = phi[i] * p[j]; break;}
    			mu[p[j] * i] = -mu[i],phi[i * p[j]] = phi[i] * phi[p[j]];
    		}
    	}
    	for (int i = 1; i <= M; i++) mu[i] += mu[i - 1],phi[i] += phi[i - 1];
    }
    LL getmu(int x)
    {
    	if (x <= M) return mu[x];
    	if (fm[x]) return fm[x];
    	LL res = 1LL;
    	for (LL l = 2,r; l <= x; l = r + 1)
    		r = x / (x / l),res -= (LL)(r - l + 1) * getmu(x / l);
    	return fm[x] = res;
    }
    LL getp(int x)
    {
    	if (x <= M) return phi[x];
    	if (fp[x]) return fp[x];
    	LL res = (LL)x * (x + 1LL) / 2;
    	for (LL l = 2,r; l <= x; l = r + 1)
    		r = x / (x / l),res -= (LL)(r - l + 1) * getp(x / l);
    	return fp[x] = res;
    }
    int main()
    {
    	init(),scanf("%d",&T);
    	for (; T; T--) scanf("%d",&n),printf("%lld %lld\n",getp(n),getmu(n));
    }
    
  • 相关阅读:
    linux常用命令笔记
    head first html与css
    多线程编程核心技术日记
    nio
    排序算法
    随笔
    数据库读写分离
    购物网站设计
    http
    servlet初始化
  • 原文地址:https://www.cnblogs.com/nibabadeboke/p/15986726.html
Copyright © 2020-2023  润新知