hdu 1695
来源:互联网 发布:装饰工程报价软件 编辑:程序博客网 时间:2024/06/09 22:31
链接:http://http://acm.hdu.edu.cn/showproblem.php?pid=1695
题意:在(a,b)找x,在(c,d)找y,使得gcd(x,y)=k;
其中a=c=1;
这样就可理解为x在(1,b/k),y在(1,d/k)且x,y互质
介绍两种方法
第一种容斥定理
还是直接看代码,不解释
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN = 10000;int prime[MAXN+1];void getPrime(){ memset(prime,0,sizeof(prime)); for(int i = 2;i <= MAXN;i++) { if(!prime[i])prime[++prime[0]] = i; for(int j = 1;j <= prime[0] && prime[j] <= MAXN/i;j++) { prime[prime[j]*i] = 1; if(i%prime[j] == 0)break; } }}long long factor[100][2];int fatCnt;int getFactors(long long x){ fatCnt = 0; long long tmp = x; for(int i = 1; prime[i] <= tmp/prime[i];i++) { factor[fatCnt][1] = 0; if(tmp%prime[i] == 0) { factor[fatCnt][0] = prime[i]; while(tmp%prime[i] == 0) { factor[fatCnt][1]++; tmp /= prime[i]; } fatCnt++; } } if(tmp != 1) { factor[fatCnt][0] = tmp; factor[fatCnt++][1] = 1; } return fatCnt;}int euler[100010];void getEuler(){ memset(euler,0,sizeof(euler)); euler[1] = 1; for(int i = 2;i <= 100000;i++) if(!euler[i]) for(int j = i; j <= 100000;j += i) { if(!euler[j]) euler[j] = j; euler[j] = euler[j]/i*(i-1); }}int calc(int n,int m)//n < m,求1-n内和m互质的数的个数{ getFactors(m); int ans = 0; for(int i = 1;i < (1<<fatCnt);i++) { int cnt = 0; int tmp = 1; for(int j = 0;j < fatCnt;j++) if(i&(1<<j)) { cnt++; tmp *= factor[j][0]; } if(cnt&1)ans += n/tmp; else ans -= n/tmp; } return n - ans;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); getPrime(); int a,b,c,d; int T; int k; scanf("%d",&T); int iCase = 0; getEuler(); while(T--) { iCase++; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k == 0 || k > b || k > d) { printf("Case %d: 0\n",iCase); continue; } if(b > d)swap(b,d); b /= k; d /= k; long long ans = 0; for(int i = 1;i <= b;i++) ans += euler[i]; for(int i = b+1;i <= d;i++) ans += calc(b,i); printf("Case %d: %I64d\n",iCase,ans); } return 0;}
第二种莫比乌斯反演
初学就转载了http://www.cnblogs.com/kuangbin/archive/2013/08/21/3273440.html
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN = 1000000;bool check[MAXN+10];int prime[MAXN+10];int mu[MAXN+10];void Moblus(){ memset(check,false,sizeof(check)); mu[1] = 1; int tot = 0; for(int i = 2; i <= MAXN; i++) { if( !check[i] ) { prime[tot++] = i; mu[i] = -1; } for(int j = 0; j < tot; j++) { if(i * prime[j] > MAXN) break; check[i * prime[j]] = true; if( i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } else { mu[i * prime[j]] = -mu[i]; } } }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; int a,b,c,d,k; Moblus(); scanf("%d",&T); int iCase = 0; while(T--) { iCase++; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k == 0) { printf("Case %d: 0\n",iCase); continue; } b /= k; d /= k; if(b > d)swap(b,d); long long ans1 = 0; for(int i = 1; i <= b;i++) ans1 += (long long)mu[i]*(b/i)*(d/i); long long ans2 = 0; for(int i = 1;i <= b;i++) ans2 += (long long)mu[i]*(b/i)*(b/i); ans1 -= ans2/2; printf("Case %d: %I64d\n",iCase,ans1); } return 0;}
0 0
- hdu 1695
- HDU 1695
- hdu 1695
- HDU 1695
- Hdu 1695
- hdu 1695 hdu 2841 容斥原理
- HDU 1695 GCD 数论
- hdu 1695 GCD
- hdu 1695 GCD
- HDU 1695 GCD (数论)
- hdu 1695 GCD
- HDU 1695 GCD
- HDU 1695 GCD
- HDU - 1695 GCD
- HDU 1695 GCD
- HDU 1695 GCD
- HDU 1695(容斥)
- HDU 1695 GCD
- Qt Creator窗口布局
- java的instanceof()方法
- quick-lua中脚本和资源的加密
- find查找所以文件字符串命令
- lua里table转string(序列化)和string转table(反序列化)
- hdu 1695
- webBrowser1_DocumentCompleted执行两次
- 重写www.zju.edu.cn后的总结
- 前端编码规范之CSS
- Linux下修改MySql最大连接数-亲自试验
- JAVA-2015-04-24应该思考的东西
- leetCode : Length of Last Word
- 饼图柱状图插件 highcharts
- jenkins java rest api 创建JOB