传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301
题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k。
题解:和前几道题差不多,就是xy不是从1开始了,所以我们很容易联想到容斥原理,ans=gcd(b,d)-gcd(a-1,d)-gcd(b,c-1)+gcd(a-1,b-1)。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <deque> #include <queue> #include <iterator> #include <stack> #include <map> #include <set> #include <algorithm> #include <cctype> using namespace std; #define si1(a) scanf("%d",&a) #define si2(a,b) scanf("%d%d",&a,&b) #define sd1(a) scanf("%lf",&a) #define sd2(a,b) scanf("%lf%lf",&a,&b) #define ss1(s) scanf("%s",s) #define pi1(a) printf("%d\n",a) #define pi2(a,b) printf("%d %d\n",a,b) #define mset(a,b) memset(a,b,sizeof(a)) #define forb(i,a,b) for(int i=a;i<b;i++) #define ford(i,a,b) for(int i=a;i<=b;i++) typedef long long LL; const int N=500005; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-7; LL f[N]; LL k; LL xiaohao(LL n,LL m) { if(n<k||m<k) return 0; if(n>m) swap(n,m); n/=k; m/=k; LL sum=0; for(LL i=n;i>=1;i--) { f[i]=(n/i)*(m/i); for(LL j=i+i;j<=n;j+=i) f[i]-=f[j]; } return f[1]; } int main() { // freopen("input.txt","r",stdin); LL a,b,c,d; int T; scanf("%d",&T); while(T--) { //scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k); cin>>a>>b>>c>>d>>k; if(a>b||c>d) { puts("0"); continue; } cout<<xiaohao(b,d)-xiaohao(a-1,d)-xiaohao(c,b-1)+xiaohao(a-1,b-1)<<endl; } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <deque> #include <queue> #include <iterator> #include <stack> #include <map> #include <set> #include <algorithm> #include <cctype> using namespace std; #define si1(a) scanf("%d",&a) #define si2(a,b) scanf("%d%d",&a,&b) #define sd1(a) scanf("%lf",&a) #define sd2(a,b) scanf("%lf%lf",&a,&b) #define ss1(s) scanf("%s",s) #define pi1(a) printf("%d\n",a) #define pi2(a,b) printf("%d %d\n",a,b) #define mset(a,b) memset(a,b,sizeof(a)) #define forb(i,a,b) for(int i=a;i<b;i++) #define ford(i,a,b) for(int i=a;i<=b;i++) typedef long long LL; const int N=50000; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-7; LL x; LL A,B,C,D,K; LL mu[N+10],sum[N+10],prime[N+10]; bool com[N+1]; void GetPrimes() { memset(com,0,sizeof(com)); mu[1]=1; x=0; for(LL i=2;i<=N;++i) { if (!com[i]) { prime[x++] = i; mu[i] = -1; } for (LL j=0;j<x&&i*prime[j]<=N;++j) { com[i*prime[j]] = true; if (i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } } for (LL i=1;i<=N;++i) sum[i] = sum[i-1] + mu[i]; } LL Process(LL n,LL m) { LL res=0; if(n>m) swap(n,m); for(LL i=1,last=0;i<=n;i=last+1) { last=min(n/(n/i),m/(m/i)); res+=(sum[last]-sum[i-1])*(n/i)*(m/i); } return res; } int main() { // freopen("input.txt","r",stdin); GetPrimes(); int T; scanf("%d",&T); while(T--) { scanf("%lld%lld%lld%lld%lld",&A,&B,&C,&D,&K); LL ans=0; ans+=Process(B/K,D/K); ans-=Process((A-1)/K,D/K); ans-=Process(B/K,(C-1)/K); ans+=Process((A-1)/K,(C-1)/K); printf("%lld\n",ans); } }