bzoj 1101

其实这个用的是Mobius反演的第二种形式

F(d) = (n div d) * (m div d)

f(d) = [ gcd(i,j)=d ] (i in [1,a], j in [1,b])

 1 /**************************************************************
 2     Problem: 1101
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:6764 ms
 7     Memory:1688 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <iostream>
12 using namespace std;
13
14 typedef long long dnt;
15
16 int prm[6000], isnot[50010], mu[50010], ptot;
17
18 void init( int n ) {
19     mu[1] = 1;
20     for( int i=2; i<=n; i++ ) {
21         if( !isnot[i] ) {
22             prm[++ptot] = i;
23             mu[i] = -1;
24         }
25         for( int j=1; j<=ptot && i*prm[j]<=n; j++ ) {
26             isnot[i*prm[j]] = true;
27             if( i%prm[j]==0 ) {
28                 mu[i*prm[j]] = 0;
29                 break;
30             }
31             mu[i*prm[j]] = -mu[i];
32         }
33     }
34     for( int i=1; i<=n; i++ )
35         mu[i] += mu[i-1];
36 }
37 dnt calc( int n, int m, int k ) {
38     dnt rt = 0;
39     if( n>m ) swap(n,m);
40     n/=k;
41     m/=k;
42     for( int d=1; d<=n; d++ ) {
43         int dd=min(n/(n/d),m/(m/d));
44         rt += (dnt)(n/d)*(m/d)*(mu[dd]-mu[d-1]);
45         d=dd;
46     }
47     return rt;
48 }
49 int main() {
50     init(50000);
51     int T;
52     scanf( "%d", &T );
53     while( T-- ) {
54         int n, m, k;
55         scanf( "%d%d%d", &n, &m, &k );
56         printf( "%lld\n", calc(n,m,k) );
57     }
58 }

时间: 2024-10-12 18:16:56

bzoj 1101的相关文章

bzoj 1101 [POI2007]Zap - 莫比乌斯反演

Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(1<=n<= 50000)接下来n行,每行表示一个询问,每行三个 正整数,分别为a,b,d.(1<=d<=a,b<=50000) Output 对于每组询问,输出到输出文件zap.out一个正

BZOJ 1101 [POI2007]Zap(莫比乌斯反演)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1101 [题目大意] 求[1,n][1,m]内gcd=k的情况 [题解] 考虑求[1,n][1,m]里gcd=k 等价于[1,n/k][1,m/k]里gcd=1 考虑求[1,n][1,m]里gcd=1 结果为sum(miu[d]*(n/d)*(m/d)) 预处理O(n^1.5) 由于n/d只有sqrt(n)种取值,所以可以预处理出miu[]的前缀和 询问时分段求和 [代码] #incl

bzoj 1101 zap 莫比乌斯

1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MB Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(1<=n<= 50000)接下来n行,每行表示一个询问,每行三个正整数,分别为a,b,d.(

BZOJ 1101 Zap(莫比乌斯反演)

http://www.lydsy.com/JudgeOnline/problem.php?id=1101 给定a,b,d,求有多少gcd(x,y)==d(1<=x<=a&&1<=y<=b) 思路: Σgcd(x,y)==d  (1<=x<=a,1<=y<=b) = Σgcd(x,y)==1 (1<=x<=a/d,1<=y<=b/d) 令G(i)=num(i|gcd(x,y))=n/i*m/i g(i)=num(i=gc

BZOJ 1101([POI2007]Zap-满足x&lt;=a&amp;&amp;y&lt;=b&amp;&amp;gcd(x,y)=d的数对个数)

1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1646  Solved: 577 [Submit][Status][Discuss] Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(

bzoj 1101 Zap —— 莫比乌斯反演

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1101 直接莫比乌斯反演. 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=5e5+5; int pri[xn],cnt,mu[xn]; bool vis[xn]; int rd()

bzoj 1101: [POI2007]Zap

裸的莫比乌斯反演 1 #include<bits/stdc++.h> 2 #define N 100005 3 #define M 10000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<'0' || ch>'9') {if (ch=='-')

BZOJ 1101 Zap

莫比乌斯反演裸题. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define maxn 50050 using namespace std; int n,a,b,d,pre[maxn],miu[maxn],prime[maxn],cnt=0; bool vis[maxn]; void make_table() { miu[1]=1; for (int i=2;i

bzoj 1101 莫比乌斯反演

最裸的莫比乌斯 #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e5 + 7; const int M = 1e6 + 7; const int inf = 0x3f3f3f3f; const LL INF