标签:iso diff prime describe space += sid several eof
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12935 Accepted Submission(s): 4905
/* * @Author: LyuC * @Date: 2017-10-06 17:08:18 * @Last Modified by: LyuC * @Last Modified time: 2017-10-07 15:16:16 */ /* 题意:给你两个区间[a,b],[c,d],让你找有多少对(x,y)满足,x在[a,b], y在[c,d],gcd(x,y)==k 思路:因为gcd(x,y)==k,所以x/k,y/k的最大公因子是1,也就是互质,因为 他俩最大的因子都去掉了,所以问题转化为在[1,b/k],[1,d/k]区间内, 找有多少对互质的数 用上莫比乌斯反演: 设F[n]为gcd(x,y)==n的倍数的数对的数量 f[n]为gcd(x,y)==n的数对的数量 很显然 F[n]=Sigma(d|n)( f(d) ); 那么 f[n]=sigma(n|d)( u(d/n)*F[d] ); 我们要的是f[1],所以 f[1]=u[1]*F[1]+u[2]*F[2]+...+u[min(d/k,b/k)]*F[min(d/k,b/k)]; 这种情况下多算了很多: 假设b<d 那么实际上是算了两边,但是不能单纯的除2,因为(x,x)这样的算了一边 所以 res1=从1到min(b,d)的结果 res2=从1到max(b,d)的结果 res=res2-res1/2;
这个在纸上画一下就很清楚了 */ #include <bits/stdc++.h> #define MAXN 100005 #define LL long long using namespace std; int t; int a,b,c,d; int k; int f[MAXN]; bool check[MAXN]; int mu[MAXN]; int prime[MAXN]; LL res1; LL res2; inline void mobi(){ memset(check,false,sizeof check); mu[1]=1; int tol=0; for(int i=2;i<MAXN;i++){ if(!check[i]){ prime[tol++]=i; mu[i]=-1; } for(int j=0;j<tol;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]; } } } } inline void init(){ res1=0; res2=0; } int main(){ // freopen("in.txt","r",stdin); mobi(); scanf("%d",&t); for(int ca=1;ca<=t;ca++){ init(); printf("Case %d: ",ca); scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k==0){ puts("0"); continue; } b/=k; d/=k; if(b>d){ swap(b,d); } for(int i=1;i<=b;i++){ res1+=(LL)mu[i]*(b/i)*(b/i); } for(int i=1;i<=b;i++){ res2+=(LL)mu[i]*(b/i)*(d/i); } printf("%lld\n",res2-res1/2); } return 0; }
标签:iso diff prime describe space += sid several eof
原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/7634822.html