zoukankan      html  css  js  c++  java
  • Min25 筛学习笔记

    仅仅是 (min25) 筛最基本的方法,没有任何推式子的例题。(想了想还是加两道吧qwq)
    这里解决的是 (Luogu) 那道模板题。
    min25 基本方法:
    最基础的是两个式子:

    [G(n,m): 所有合数 space x le n space 的最小质因子 > pri_m 的 space p^k 和或者是质数 space x le n space 的space p^k 的和。\ G(n,m) = G(n,m - 1) - pri_m^k imes (G(frac n{pri_m},m - 1) - G(pri_m - 1,m - 1))\ S(n,m): 对于所有 space xle nspace 且最小质因数 > pri_m 的 p(x) 的和。\ S(n,m) = G(n,cnt) - G(pri_m,cnt) + pri_i^e imes S(frac n {pri_i^e},i)(i > m,pri_i^e le n) ]

    用途: 求积性函数前缀和。
    要求: (f(p^k)) ((p) 是质数)能够写成低阶多项式的形式。

    时间: (O(n^{1-in})) ,操过 (10^{10}) 不成问题。

    怎么做:((pri) 均表示合数的最小质因数,故必须满足 (pri^2le n))((pri_k) 表示第 (k) 个质数)

    1. 类似 (dp) 状态构造出 (S(n,k)) 表示所有小于等于 (n) 的质数,或者满足最小质因子大于(pri_k) 的合数所贡献的所有答案。
    2. 分为质数与合数统计答案,(S(n,k) = G(k+1 space tospace n [的质数贡献]) + f(pri_i^e) S(frac n {pri_i^e},i)(i > k,pri_i^ele n,pri_i^2le n)) 合数递归求解,质数提前与处理。
    3. 质数通过同样的方式,设 (G(n,k)) 表示前 (n) 个数最小质因子大于 (pri_k) 的合数或者是质数的单项式贡献。
    4. 因为我们最后仅仅关心 (G(n,cnt)) ,既所有质数的答案。所以我们仅需要计算 (G(n)) 即可。
    5. (G(n,cnt) = G(n,cnt - 1) + pri_{cnt}^k G(lfloorfrac n { pri_{cnt}} floor,cnt - 1) (pri_{cnt}^2 le n)) 。因为 (n) 可能会很大,但因为整除的缘故,只需要保留 (sqrt n)(G(n)) 即可。
    6. 将最后没有被加上的 (1) 加上。

    一些问题的探究:

    Q: 积性函数这条性质到底用在了哪里?

    A: 对于求 (S) 的板块,求合数的贡献时,本就将其的最小质因子分开来做了,这里需要 (f) 是一个积性函数。

    ​ 对于求 (G) 的板块,因为我们是将 (p^k) 的多项式拆开贡献求的,所以这里 (G) 维护的其实是一个完全积性函数的贡献,所以这里将其拆开做是对的。

    Q: 为啥 (f(p^k)) 要求写成低阶多项式的形式?

    A: (G) 就是这么构造的呀!假如说放在另外一个地方来看的话,我们要求 (5^{233} + 4^{114514} + 3^{1919810} + 2 ^ {19260817}) 的话,我们的 (S) 便是求总的答案的,而 (G) 是求得诸如 (2^{19260817}) 这样的单项式的。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N = 1e6 + 10,inv = 333333336;
    const int Mod = 1e9 + 7;
    ll n,m,sq;
    ll sp1[N],sp2[N];
    int pri[N],cnt = 0,vis[N];
    ll g1[N],g2[N],val[N],tot;
    ll Map1[N],Map2[N];
    inline void Prime() {
    	for(int i = 2;i <= sq;i++) {
    		if(!vis[i]) {
    			pri[++cnt] = i;
    			sp1[cnt] = sp1[cnt - 1] + i;
    			sp2[cnt] = sp2[cnt - 1] + 1ll * i * i % Mod;
    			if(sp1[cnt] > Mod) sp1[cnt] -= Mod;
    			if(sp2[cnt] > Mod) sp2[cnt] -= Mod;
    		}
    		for(int j = 1;j <= cnt && 1ll * pri[j] * i <= sq ;j++) {
    			vis[pri[j] * i] = true;
    			if(i % pri[j] == 0) break;
    		}
    	}
    }
    inline ll S(ll now,int k) {
    	if(now <= pri[k]) return 0;
    	int loc = now <= sq ? Map1[now] : Map2[n / now]; 
    	ll res = g2[loc] - g1[loc] + sp1[k] - sp2[k] + Mod * 2,tem;
    	res %= Mod;
    	for(int i = k + 1;i <= cnt && 1ll * pri[i] * pri[i] <= now;i++) {//最小质因数 平方要小于等于原数
    		for(ll j = pri[i],total = 1;j <= now;total++,j *= pri[i]) {
    			tem = j % Mod;
    			res = res + tem * (tem - 1) % Mod * (S(now / j,i) + (total != 1)) % Mod; //注意细节,total 是用来计算所有f(p^k) 的值的,因为此时递归计算的最小质因数必须 > pri_i 所以不会计算到,所以要加上这一条。
    			if(res > Mod) res -= Mod;
    		}
    	}
    	return res;
    }
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0),cout.tie(0);
    	cin >> n;
    	sq = sqrt(n);
    	Prime();
    	for(ll l = 1,r;l <= n;l = r + 1) {//G(n,1)赋初值
    		r = (n / (n / l));
    		val[++tot] = n / l;
    		g1[tot] = val[tot] % Mod;
    		g2[tot] = g1[tot] * (g1[tot] + 1) / 2 % Mod * inv % Mod * (2 * g1[tot] + 1) % Mod;
    		g2[tot]--;
    		g1[tot] = g1[tot] * (g1[tot] + 1) / 2 % Mod - 1;
    		if(n / l <= sq) Map1[n / l] = tot;
    		else Map2[n / (n / l)] = tot;
    		if(g1[tot] < 0) g1[tot] += Mod;
    		if(g2[tot] < 0) g2[tot] += Mod;
    	}
    	for(int i = 1;i <= cnt;i++) {//算每一个可能会用到的 G(n,k)
    		for(int j = 1;j <= tot && 1ll * pri[i] * pri[i] <= val[j];j++) {//注意最小质因数 平方要小于等于原数
    			int k = (val[j] / pri[i] <= sq ? Map1[val[j] / pri[i]] : Map2[n / (val[j] / pri[i])]);
    			g1[j] = g1[j] - (g1[k] - sp1[i - 1]) * pri[i] % Mod;
    			g2[j] = g2[j] - (g2[k] - sp2[i - 1]) * pri[i] % Mod * pri[i] % Mod;
    			if(g1[j] < 0) g1[j] += Mod;
    			if(g2[j] < 0) g2[j] += Mod;
    		}
    	}
    	ll ans = S(n,0) + 1;
    	cout << (ans >= Mod ? ans - Mod : ans) << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    高斯消元
    UVa12103
    UVa10294
    UVa11762
    牛客网算法工程师能力评估
    华为研发工程师编程题
    网易2017春招笔试真题编程题集合
    2017网易有道内推编程题
    2017网易雷火实习生招聘编程题
    数组---面试知识点整理
  • 原文地址:https://www.cnblogs.com/jojojojojob/p/14416298.html
Copyright © 2011-2022 走看看