题目要求找到给定区间的化简后分子分母的和小于1000的数字的个数
我的想法是先找到所有的满足要求的最简分数(总数不超过1e6,而且远小于),然后对询问查找每个最简分数出现的次数.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cctype>
#include<queue>
#include<set>using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e3+5; struct node
{int x,y;
}aa[MAXN*MAXN];
int tot;int gcd(int a,int b)
{return b==0?a:gcd(b,a%b);
}void init()
{tot=0;for(int i=1;i<999;i++){aa[tot].x=1; aa[tot].y=i;tot++;}for(int i=2;i<999;i++){aa[tot].x=i; aa[tot].y=1;tot++;}for(int i=2;i<1000;i++){for(int j=2;j<1000;j++){if(i+j>=1000) break;if(gcd(i,j)!=1) continue;aa[tot].x=i; aa[tot].y=j;tot++;}}
}ll A,B,C,D;
ll ans,k1,k2,k3,k4;ll deal(ll a,ll b,ll c,ll d)
{if(a>b || c>d) return 0;if(c>b || d<a) return 0;ll x=max(a,c);ll y=min(b,d);return y-x+1;
}int main()
{//freopen("data.in","r",stdin);init();while(~scanf("%lld%lld%lld%lld",&A,&B,&C,&D)){ans=0;for(int i=0;i<tot;i++){if(A%aa[i].x==0) k1=A/aa[i].x;else k1=A/aa[i].x+1;k2=B/aa[i].x;if(C%aa[i].y==0) k3=C/aa[i].y;else k3=C/aa[i].y+1;k4=D/aa[i].y;ll tmp=deal(k1,k2,k3,k4);if(tmp>0){ans+=tmp;//printf("%d/%d %d\n",aa[i].x,aa[i].y,tmp);}}printf("%lld\n",ans);}return 0;
}