bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数。例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0。 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b)。

Input

第一行一个数T,表示询问数。 接下来T行,每行两个数a,b,表示一个询问。

Output

对于每一个询问,输出一行一个非负整数作为回答。

Sample Input

4
7558588 9653114
6514903 4451211
7425644 1189442
6335198 4957

Sample Output

35793453939901
14225956593420
4332838845846
15400094813

Hint

【数据规模】
T<=10000
1<=a,b<=10^7



  题目大意 定义函数为数x所含质因子的最大幂指数。求

  继续用之前的套路统计每个f被计算的次数,然后将gcd化为莫比乌斯函数之和。

  

  如果这样,似乎并没有什么好方法求值,所以试试把那几个向下取整的分数搞到外层来,这样就可以找机会分段处理。于是得到了下面这个式子:

  好了问题来了,如何把后面的值快速预处理出来,前面的是可以通过分段降低时间复杂度。

  为了方便描述,所以我们设

  为了更好地理解证明,你需要清楚一个东西,就是对于一个非空有限集合S,满足。至于它的证明,考虑S的k元素子集的个数,然后二项式定理搞成(1-1)的某次幂。

  由于我比较笨,不会大佬们的分类讨论做法。就用集合论乱搞骗结论。

  首先对n进行质因数分解,得到。然后设(是P‘的补集)。

  根据莫比乌斯函数的性质,对于任何一个数有一个质因子的幂指数大于1,则它的莫比乌斯函数值为0,即为了使式子对答案有贡献,就应当满足,当d分解后,pi的幂指数要么是ai要么是ai - 1然后有

  式子中A的意义大概就是它里面的质因子pi的幂指数就是ai - 1.

  然后根据这个又可以得到一个事实,中间的max一坨的取值要么是a要么是(a - 1)。所以我们可以把它拆成两部分求和。

  一部分是包含整个P‘,所以此时那一坨的取值为a-1,另一部分是只包含P‘的一部分,所以此时那一坨的取值为a。

  

  然后前一部分事实上可以把A拆成的子集和P‘的并集,后一部分也可以把A拆成P‘的真子集和的子集。

  然后发现左右两边的求和符号可以合并。于是得到了

  接下来考虑

  1) 如果它不为空的话,那么意味着求和符号下的值为0。换言之,就是n中的所有幂指数不相等,那么就有

  2) 如果它为空的话,意味着求和符号的值为1,P‘的大小就是k,那么就有

  然后有什么用呢?

  考虑预处理,由于1e7的凶残数据范围所以不能够O(nlogn)预处理。就考虑线性筛。

  这里要用到线性筛一个很重要的性质,每个合数保证被其最小的质因子筛掉。所以,我们只需要记录每个数的最小质因子的次数pos。

  这样在prime[j]不整除i的时候我们就可以轻松处理掉(判断最小质因子的次数是否为1,g(i)是否为0)。

  现在考虑prime[j]整除i的时候,通过常用套路,我们考虑i把prime[j]除尽后的数x和 i / x * prime[j]。此时显然可以判断一下pos[x]和pos[i] + 1是否相等,更新g值就好了。

  因此,我们还需要记录这个数的最小质因子去除这个数,直到不能再除后得到的数。这些记录的东西都可以在线性筛中得到(假设读者都会,就直接贴代码了)。

  我表示这是有史以来我写过最长的题解和最短的模板(bits/std++.h直接抵掉我15行左右的include)。

Code

 1 /**
 2  * bzoj
 3  * Problem#3309
 4  * Accepted
 5  * Time:11804ms
 6  * Memory:170040k
 7  */
 8 #include <bits/stdc++.h>
 9 #ifndef WIN32
10 #define Auto "%lld"
11 #else
12 #define Auto "%I64d"
13 #endif
14 using namespace std;
15 typedef bool boolean;
16
17 #define LL long long
18
19 const int limit = 1e7;
20
21 int num = 0;
22 int prime[700100];
23 boolean vis[limit + 1];
24 int last[limit + 1];
25 int posm[limit + 1];
26 LL g[limit + 1];
27 inline void Euler() {
28     memset(vis, false, sizeof(vis));
29     g[0] = g[1] = -1;
30     for(int i = 2; i <= limit; i++) {
31         if(!vis[i])    prime[num++] = i, last[i] = 1, posm[i] = 1, g[i] = 1;
32         for(int j = 0; j < num && i * 1LL * prime[j] <= limit; j++) {
33             int c = i * prime[j];
34             vis[c] = true;
35             if(i % prime[j]) {
36                 last[c] = i, posm[c] = 1;
37                 g[c] = (posm[i] == 1) ? (-g[i]) : (0);
38             } else {
39                 last[c] = last[i];
40                 posm[c] = posm[i] + 1;
41                 g[c] = (posm[last[c]] == posm[c] || last[c] == 1) ? (-g[last[c]]) : (0);
42                 break;
43             }
44         }
45     }
46     for(int i = 2; i <= limit; i++)
47         g[i] += g[i - 1];
48 }
49
50 int a, b;
51 inline void init() {
52     scanf("%d%d", &a, &b);
53 }
54
55 inline void solve() {
56     if(a > b)    swap(a, b);
57     long long res = 0;
58     for(int i = 1, j; i <= a; i = j + 1) {
59         j = min(a / (a / i), b / (b / i));
60         res += (a / i) * 1LL * (b / i) * (g[j] - g[i - 1]);
61     }
62     printf(Auto"\n", res);
63 }
64
65 int T;
66 int main() {
67     Euler();
68     scanf("%d", &T);
69     while(T--) {
70         init();
71         solve();
72     }
73     return 0;
74 }
时间: 2024-10-25 11:23:52

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛的相关文章

【bzoj3309】DZY Loves Math 莫比乌斯反演+线性筛

题目描述 对于正整数x,定义f(x)为x所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0.给定正整数n,m,求$\sum\limits_{i=1}^n\sum\limits_{j=1}^mf(\gcd(i,j))$ 输入 第一行一个数T,表示询问数.接下来T行,每行两个数n,m,表示一个询问. 输出 对于每一个询问,输出一行一个非负整数作为回答. 样例输入 4 7558588 9653114 6514903 445121

BZOJ 3309 DZY Loves Math 莫比乌斯反演

题目大意: 枚举d=gcd(i,j),得到 现在我们只需要知道Σ[d|T]f(d)μ(T/d)的前缀和就行了 设这个函数为g(x) 观察这个函数 由于含平方因子数的μ值都为零,因此我们只考虑μ(T/d)!=0的数 令T=p1^a1*p2^a2*...*pk^ak,d=p1^b1*p2^b2*...*pk^bk 那么0<=(ai-bi)<=1 如果存在ai≠aj(i≠j),那么我们可以将所有的a分为两部分:最大的集合A和非最大的集合B 很显然f值由A中的选取方案决定 对于A中的每种选取方案,μ值

【BZOJ】3309: DZY Loves Math 莫比乌斯反演优化

3309: DZY Loves Math Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample In

bzoj 3309 DZY Loves Math

LINK:DZY Loves Math 一道比较有意思的数论题 原谅我的智障多调了40min. 可以简单的推式子推出 答案为\(\sum{w=1}^n\frac{n}{w}\frac{m}{w}\sum{x|w}\mu(x)f(\frac{w}{x})\) f函数定义和题目中一致. 考虑后面前缀和怎么求 发现光求f(x)复杂度都比较高.如果我们把f(x)求出再调和级数预处理 那得GG 1e7过不了log+根号 考虑考虑一下\(\mu\)和f的这种形式肯定值有局限 设后面的东西为g(x) 不难发现

bzoj 3309 DZY Loves Math——反演+线性筛

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3309 像这种数据范围,一般是线性预处理,每个询问 sqrt (数论分块)做. 先反演一番.然后 f( ) 还不能一个就花 log 的时间,所以要分析性质. 设 n 一共 m 个质因数,其中最大的指数是 t . 已有 Σ(d|n) f(d)*u(n/d) ,如果 u( ) 的部分含有指数>=2的质因子,就无贡献:所以 u( ) 里每种质因数选1个或0个,一共 2^m 种. 如果 n 里有一个

莫比乌斯反演 bzoj 3309 DZY Loves Math

好久没有写反演了 感觉不会了 首先推一个经典的式子啊 \[ans = \sum_{D=1}^{n}\sum_{d|D}f(d)\mu(\frac{D}{d})\frac{n}{D}\frac{m}{D}\] 记\(g(D) = \sum_{d|D}f(d)\mu(\frac{D}{d})\) 结论挺好找的啊 把一个数拆成\({p_k}^{a_k}\)形式 如果所有\(a_k\)相同 那么\(g(D) = (-1)^{k+1}\) 否则\(g(D) = 0\) 证明就考虑两个集合 所有次幂为最大的

【bzoj4407】于神之怒加强版 莫比乌斯反演+线性筛

题目描述 给下N,M,K.求 输入 输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示. 输出 如题 样例输入 1 2 3 3 样例输出 20 题解 莫比乌斯反演+线性筛 $\sum\limits_{i=1}^n\sum\limits_{j=1}^m\gcd(i,j)^k\\=\sum\limits_{d=1}^{\min(n,m)}d^k\sum\limits_{i=1}^n\sum\limits

BZOJ 2693: jzptab [莫比乌斯反演 线性筛]

2693: jzptab Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1194  Solved: 455[Submit][Status][Discuss] Description Input 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M Output T行 每行一个整数 表示第i组数据的结果 Sample Input 1 4 5 Sample Output 122 HINT T <= 10000 N, M<=1000000

hdu.5212.Code(莫比乌斯反演 &amp;&amp; 线性筛)

Code Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 300    Accepted Submission(s): 124 Problem Description WLD likes playing with codes.One day he is writing a function.Howerver,his computer b