2 1 3 1 5 1 1 11014 1 14409 9
Case 1: 9 Case 2: 736427HintFor the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
题目大意:
解题思路:从1~a区间取一个数x,从1~b区间取一个数y,问你gcd(x,y)=k有多少种方案?其中x1,y1和y1,x1算同一种方案。
解题代码:那么就是 从1~b/k 取一个数x , 与 从1~d/k 取一个数y 互质的方案数,利用容斥,枚举 x,求出y的个数即可。
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <map> #include <algorithm> using namespace std; typedef long long ll; const int maxn=450; bool isPrime[maxn]; vector <int> v; int tol,a,b,c,d,k; void get_prime(){ memset(isPrime,true,sizeof(isPrime)); for(int i=2;i<maxn;i++){ if(isPrime[i]){ tol++; v.push_back(i); } for(int j=0;j<tol && i*v[j]<maxn;j++){ isPrime[i*v[j]]=false; if(i%v[j]==0) break; } } } inline vector <int> getPrime(ll x){ vector <int> tmp; for(ll i=0;i<tol && x>=v[i]*v[i];i++){ if(x%v[i]==0){ tmp.push_back(v[i]); while(x>0 && x%v[i]==0) x/=v[i]; } } if(x>1) tmp.push_back(x); return tmp; } inline ll getCnt(int i,int y){//1-y与i不互质的数的个数 vector <int> tmp=getPrime(i); int vsize=tmp.size(); ll sum=0; for(int t=1;t<(1<<vsize);t++){ int cnt=0,all=1; for(int j=0;j<vsize;j++){ if(t&(1<<j)){ all*=tmp[j]; cnt++; } } if(cnt&1) sum+=y/all; else sum-=y/all; } return sum; } void solve(){ if(k==0 || k>b || k>d){ cout<<0<<endl; return; } int x=b/k,y=d/k; if(x<y) swap(x,y); ll ans=0; for(int i=1;i<=x;i++){ int r=i>y?y:i; ans+=r; ans-=getCnt(i,r); } cout<<ans<<endl; } int main(){ get_prime(); int t; scanf("%d",&t); for(int i=1;i<=t;i++){ scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); printf("Case %d: ",i); solve(); } return 0; }
HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理),布布扣,bubuko.com
HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)
原文:http://blog.csdn.net/a1061747415/article/details/38320975