【HDU 6053 TrickGCD】 + 莫比乌斯反演
2017-07-28 10:49
381 查看
TrickGCD
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1002 Accepted Submission(s): 389
Problem Description
You are given an array A , and Zhu wants to know there are how many different array B satisfy the following conditions?
1≤Bi≤Ai
For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1…br)≥2
Input
The first line is an integer T(1≤T≤10) describe the number of test cases.
Each test case begins with an integer number n describe the size of array A.
Then a line contains n numbers describe each element of A
You can assume that 1≤n,Ai≤105
Output
For the kth test case , first output “Case #k: ” , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7
Sample Input
1
4
4 4 4 4
Sample Output
Case #1: 17
Source
2017 Multi-University Training Contest - Team 2
题意 : b[i] 可以从 1 ~ a[i] 之间选个数,任意 gcd(b[l] ~ b[r]) > 1,可以有多少中 b 数组
思路 : 枚举每个因数 o,对于 b,可以选择的数有 o * 1,o * 2,o * 3…o * b / o,有 b / o 个,对整个数组来说 贡献所有 b / o 的乘积, 预处理一下 l ~ r 之间有多少数,可以算出 o * r ~ o * (r + 1) - 1 之间的数的贡献都为 r,快速幂一下,最后利用 莫比乌斯反演去重
莫比乌斯反演是数论中的重要内容,在许多情况下能够简化运算
我们需要找到f(n)与F(n)之间的关系。从和函数定义当中,我们可以知道:
F(1)=f(1)
F(2)=f(1)+f(2)
F(3)=f(1)+ f(3)
F(4)=f(1)+f(2)+f(4)
F(5)=f(1)+f(5)
F(6)=f(1)+f(2)+f(3)+f(6)
F(7)=f(1)+f(7)
F(8)=f(1)+f(2)+f(4)+f(8)
那么:
f(1)=F(1)
f(2)=F(2)-f(1)=F(2)-F(1)
f(3) =F(3)-F(1)
f(4)=F(4) -f(2)- f(1) =F(4)-F(2)
f(5) =F(5)-F(1)
f(6)=F(6)-F(3)-F(2)+F(1)
f(7)=F(7)-F(1)
f(8)=F(8)-F(4)
从中,可以看出,若n=p2(p为质数)那么,F(p)=f(1)+f(p),F(n)=f(1)+f(p)+f(p2),所以,f(n)=F(p2)-F(p)
AC代码:
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1002 Accepted Submission(s): 389
Problem Description
You are given an array A , and Zhu wants to know there are how many different array B satisfy the following conditions?
1≤Bi≤Ai
For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1…br)≥2
Input
The first line is an integer T(1≤T≤10) describe the number of test cases.
Each test case begins with an integer number n describe the size of array A.
Then a line contains n numbers describe each element of A
You can assume that 1≤n,Ai≤105
Output
For the kth test case , first output “Case #k: ” , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7
Sample Input
1
4
4 4 4 4
Sample Output
Case #1: 17
Source
2017 Multi-University Training Contest - Team 2
题意 : b[i] 可以从 1 ~ a[i] 之间选个数,任意 gcd(b[l] ~ b[r]) > 1,可以有多少中 b 数组
思路 : 枚举每个因数 o,对于 b,可以选择的数有 o * 1,o * 2,o * 3…o * b / o,有 b / o 个,对整个数组来说 贡献所有 b / o 的乘积, 预处理一下 l ~ r 之间有多少数,可以算出 o * r ~ o * (r + 1) - 1 之间的数的贡献都为 r,快速幂一下,最后利用 莫比乌斯反演去重
莫比乌斯反演是数论中的重要内容,在许多情况下能够简化运算
我们需要找到f(n)与F(n)之间的关系。从和函数定义当中,我们可以知道:
F(1)=f(1)
F(2)=f(1)+f(2)
F(3)=f(1)+ f(3)
F(4)=f(1)+f(2)+f(4)
F(5)=f(1)+f(5)
F(6)=f(1)+f(2)+f(3)+f(6)
F(7)=f(1)+f(7)
F(8)=f(1)+f(2)+f(4)+f(8)
那么:
f(1)=F(1)
f(2)=F(2)-f(1)=F(2)-F(1)
f(3) =F(3)-F(1)
f(4)=F(4) -f(2)- f(1) =F(4)-F(2)
f(5) =F(5)-F(1)
f(6)=F(6)-F(3)-F(2)+F(1)
f(7)=F(7)-F(1)
f(8)=F(8)-F(4)
从中,可以看出,若n=p2(p为质数)那么,F(p)=f(1)+f(p),F(n)=f(1)+f(p)+f(p2),所以,f(n)=F(p2)-F(p)
AC代码:
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int MAX = 1e5 + 10; const int mod = 1e9 + 7; typedef long long LL; LL sum[MAX],num[MAX]; LL km(LL a,LL b){ LL ans = 1; while(b){ if(b & 1) ans = (ans * a) % mod; b /= 2; a = (a * a) % mod; } return ans; } int main() { int T,nl = 0,n,x; scanf("%d",&T); while(T--){ memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&x),num[x]++; for(int i = 2; i < MAX; i++) num[i] += num[i - 1]; LL ans = 0,cut = 0; for(int i = 2; i < MAX; i++){ if(num[i - 1]) continue; // 有不满足的点 sum[i] = 1; for(int j = i; j < MAX; j += i){ if(j + i >= MAX) cut = num[MAX - 1] - num[j - 1]; // j ~ MAX else cut = num[j + i - 1] - num[j - 1]; if(!cut) continue; sum[i] = (sum[i] * km(j / i,cut)) % mod; } } for(int i = MAX - 1; i >= 2; i--) for(int j = i + i; j < MAX; j += i) sum[i] = (sum[i] - sum[j] + mod) % mod; for(int i = 2; i < MAX; i++) ans = (ans + sum[i]) % mod; printf("Case #%d: %lld\n",++nl,ans); } return 0; }
相关文章推荐
- HDU 6053 TrickGCD(莫比乌斯反演)
- HDU 6053 TrickGCD(莫比乌斯反演+前缀和)
- 2017多校训练赛第二场 HDU 6053 TrickGCD(容斥原理/莫比乌斯反演)
- HDU 6053 TrickGCD(莫比乌斯反演)
- HDU 6053 TrickGCD(莫比乌斯反演)
- 解题报告:HDU_6053 TrickGCD 莫比乌斯反演
- HDU 6053 TrickGCD (桶装+分段 / 莫比乌斯反演)
- hdu 6053 TrickGCD(莫比乌斯反演)
- (2017多校训练第二场)HDU - 6053 TrickGCD 初见莫比乌斯
- HDU 6053 TrickGCD (莫比乌斯函数)
- 2017多校联合第二场 1009题 hdu 6053 TrickGCD (超详细!!!)莫比乌斯 容斥
- hdu 6053 TrickGCD - 容斥原理 - 快速幂
- hdu 6053 trick gcd 容斥
- TrickGCD(HDU 6053 莫比乌斯函数的反演)
- hdu--6053--TrickGCD
- HDU 6053 TrickGCD(莫比乌斯函数)
- hdu 6053 TrickGCD [2017 Multi-University Training Contest - Team 2] [莫比乌斯函数]
- hdu 6053 TrickGCD(容斥,分段,莫比乌斯函数)
- HDU 6053 TrickGCD(分块)
- TrickGCD HDU - 6053(莫比乌斯函数与容斥的关系)