Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693

jzptab

【问题描述】

求:

多组询问

【输入格式】

一个正整数T表示数据组数

接下来T行 每行两个正整数 表示N、M

【输出格式】

T行 每行一个整数 表示第i组数据的结果

【样例输入】

1

4 5

【样例输出】

122

【数据范围】

T <= 10000

N, M<=10000000



题解:

即后面那个部分为 H[T],H[T]是积性函数,求详细证明的话将T和d展开为质因数次幂相乘的形式,考虑线性筛中枚举的质数与被筛数的性质即可

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 typedef long long ll;
 9 const int maxn = 1e7 + 1;
10 const int mod = 1e8 + 9;
11 int cnt;
12 int h[maxn];
13 int pri[maxn];
14 int sum[maxn];
15 bool vis[maxn];
16 inline void Scan(int &x)
17 {
18     char c;
19     bool o = false;
20     while(!isdigit(c = getchar())) o = (c != ‘-‘) ? o : true;
21     x = c - ‘0‘;
22     while(isdigit(c = getchar())) x = x * 10 + c - ‘0‘;
23     if(o) x = -x;
24 }
25 inline void Sieve()
26 {
27     h[1] = 1;
28     for(int i = 2; i <= maxn; ++i)
29     {
30         if(!vis[i]) pri[++cnt] = i, h[i] = ((-(long long) i * i % mod) + mod + i) % mod;
31         for(int j = 1; j <= cnt; ++j)
32         {
33             int s = pri[j];
34             long long k = (long long) i * s;
35             if(k > maxn) break;
36             vis[k] = true;
37             if(!(i % s))
38             {
39                 h[k] = (long long) s * h[i] % mod;
40                 break;
41             }
42             else h[k] = (long long) h[s] * h[i] % mod;
43         }
44     }
45     for(int i = 1; i <= maxn; ++i) sum[i] = (sum[i - 1] + h[i]) % mod;
46 }
47 inline int Sum(int n, int m)
48 {
49     return ((long long) n * (n + 1) >> 1) % mod * (((long long) m * (m + 1) >> 1) % mod) % mod;
50 }
51 inline int Mobius(int n, int m)
52 {
53     int res = 0, last = 0;
54     if(n > m) swap(n, m);
55     for(int i = 1; i <= n; i = last + 1)
56     {
57         last = min(n / (n / i), m / (m / i));
58         res = (res + (long long) Sum(n / i, m / i) * ((sum[last] - sum[i - 1] + mod) % mod) % mod) % mod;
59     }
60     return res;
61 }
62 int main()
63 {
64     Sieve();
65     int n;
66     Scan(n);
67     int a, b;
68     while(n--)
69     {
70         Scan(a), Scan(b);
71         printf("%d\n", Mobius(a, b));
72     }
73 }
时间: 2024-07-30 10:19:40

Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693的相关文章

【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&amp;&amp;BZOJ 2693 jzptab)

BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4

BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][Discuss] Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究

【BZOJ 2154】Crash的数字表格 (莫比乌斯+分块)

2154: Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3

Crash的数字表格(莫比乌斯反演)

Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张NM的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4 5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12

【BZOJ】【2154】Crash的数字表格

莫比乌斯反演 PoPoQQQ讲义第4题 题解:http://www.cnblogs.com/jianglangcaijin/archive/2013/11/27/3446169.html 感觉两次sqrt(n)的枚举是亮点…… RE:汗- -b 10^7是8位数,开数组少打了一个0…… 1 /************************************************************** 2 Problem: 2154 3 User: Tunix 4 Language

bzoj 2154 Crash的数字表格(莫比乌斯反演及优化)

Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12

[bzoj 2154]Crash的数字表格

Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12

【BZOJ】2154: Crash的数字表格

http://www.lydsy.com/JudgeOnline/problem.php?id=2154 题意:求$\sum_{i=1}^{n} \sum_{j=1}^{m} lcm(i, j)$, $n,m<=1e7$ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e7+10, MD=20101009; int p[N], pcnt, n, m; bool np[N];

【BZOJ 2154】Crash的数字表格

制杖了,,,求前缀和的时候$i×i$是int,然后当$i=10^7$时就喜闻乐见地爆int了,,,对拍之后查了一个下午的错才发现这个问题,,,最后枚举用的变量全都强行加上long long才A掉 #include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; typedef long long LL; const int p =