hdu 1695 GCD
// 题意: 给你区间[a,b] [c,d] 在两个区间各取一个数x,y,要求gcd(x,y)= k
// 题目给的区间中说 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000,
// 真是不知道简便方法 后面看到 Yoiu can assume that a = c = 1 in all test cases. a,c是永远等于1的
// 于是 相当于求 区间[1,b/k]和区间[1,d/k]中 互质数的对数
// 假设 b<d 那么 b/k以前的就 sigmaphi[1..b/k] phi指的是欧拉函数
// 大于 b/k 的每个数就用容斥原理进行操作
#include <iostream> #include <string> #include<sstream> #include <cmath> #include <map> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 //#define LL long long #define N 100010 struct node { int cnt; int pr[10]; }hs[N]; LL phi[N]; LL ans; void init() { int i,j; for(i=1;i<N;i++) phi[i]=i; for(i=2;i<N;phi[i]+=phi[i-1],i++ ) if(phi[i]==i) { for(j=i;j<N;j+=i) { phi[j]=phi[j]/i*(i-1); hs[j].pr[hs[j].cnt]=i; hs[j].cnt++; } } // printf("%I64d == ",phi[4]); } int b,d,k; void dfs(int deep,int n,int index,int val) { int t; for(int i=index;i<hs[n].cnt;i++) { t=val*hs[n].pr[i]; if(deep&1) ans=ans-(b/t); else ans=ans+(b/t); dfs(deep+1,n,i+1,t); } } int main() { int T; init(); scanf("%d",&T); for(int c=1;c<=T;c++) { scanf("%d %d %d %d %d",&b,&b,&d,&d,&k); // if(k==0){ printf("Case %d: 0\n",c);continue; } if(b>d) swap(b,d); b/=k; d/=k; // printf("%d %d",b,d); //ans=0; ans=phi[b]; for(int a=b+1;a<=d;a++){ ans+=b; dfs(1,a,0,1); // printf("%I64d ? \n",ans); } printf("Case %d: %I64d\n",c,ans); } return 0; }