zoukankan      html  css  js  c++  java
  • P4213 【模板】杜教筛(Sum) min_25筛

    (color{#0066ff}{ 题目描述 })

    给定一个正整数(N(Nle2^{31}-1))

    (ans_1=sum_{i=1}^nvarphi(i))

    (ans_2=sum_{i=1}^n mu(i))

    (color{#0066ff}{输入格式})

    一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问

    (color{#0066ff}{输出格式})

    一共T行,每行两个用空格分隔的数ans1,ans2

    (color{#0066ff}{输入样例})

    6
    1
    2
    8
    13
    30
    2333
    

    (color{#0066ff}{输出样例})

    1 1
    2 0
    22 -2
    58 -3
    278 -3
    1655470 2
    

    (color{#0066ff}{数据范围与提示})

    none

    (color{#0066ff}{ 题解 })

    可以用min_25筛写

    对于(varphi)

    要拆成两个,一个0次项,一个1次项

    在收集答案的时候直接加它们两个的差即可

    对于(mu)

    因为只要指数超过1,就是0了,没用的,不同统计,直接统计1次的就行

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int maxn = 2e6 + 10;
    LL g0[maxn], g1[maxn], a[maxn];
    int pri[maxn];
    int m, sqt, n, tot;
    int getid(LL x) { return x <= sqt? x : m - n / x + 1; }
    LL getphi(LL a, int b) {
    	if(a < pri[b]) return 0;
    	LL ans = (g1[getid(a)] - g1[getid(pri[b - 1])]) - (g0[getid(a)] - g0[getid(pri[b - 1])]);
    	for(int i = b; i <= tot && (LL)pri[i] * pri[i] <= a; i++) 
    		for(LL x = pri[i], f = pri[i] - 1; x * pri[i] <= a; x *= pri[i], f *= pri[i])
                 //phi[p^2]的贡献是p*(p-1)
    			ans += (getphi(a / x, i + 1) * f + f * pri[i]);
    	return ans;
    }
    LL getmu(LL a, int b) {
    	if(a < pri[b]) return 0;
    	LL ans = -g0[getid(a)] + g0[getid(pri[b - 1])];
        //只需枚举质数,次数就是1即可
    	for(int i = b; i <= tot && (LL)pri[i] * pri[i] <= a; i++)
            //乘的那个f是-1,所以直接减,加的那个f是平方项=0, 不用管
    		ans -= getmu(a / pri[i], i + 1);
    	return ans;
    }
    int main() {
    	for(int T = in(); T --> 0;) {
    		n = in();
    		sqt = sqrt(n);
    		m = tot = 0;
    		for(int i = 1; i <= n; i = a[m] + 1)
    			a[++m] = n / (n / i), g0[m] = a[m] - 1, g1[m] = a[m] * (a[m] + 1) / 2 - 1;
    		for(int i = 2; i <= sqt; i++) {
    			if(g0[i] != g0[i - 1]) {
    				LL sqr = i * i;
    				pri[++tot] = i;
    				for(int j = m; a[j] >= sqr; j--) {
    					int id = getid(a[j] / i);
    					g0[j] -= g0[id] - g0[i - 1];
    					g1[j] -= i * (g1[id] - g1[i - 1]);
    				}
    			}
    		}
    		printf("%lld %lld
    ", getphi(n, 1) + 1, getmu(n, 1) + 1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    在ASP.NET MVC中使用DropDownList引用。呵呵。
    获取泛型对象
    Tomcat JVM 初始化加大内存
    Tomcat6.0 连接池的配置
    @ResponseBody与Ajax
    c3po数据库连接池中取出连接
    SpringMVC
    JQuery发送Ajax请求
    Java生成验证码
    Spring初学
  • 原文地址:https://www.cnblogs.com/olinr/p/10284336.html
Copyright © 2011-2022 走看看