题意是农夫站在(0,0) 在(1,1)-(m,n)的矩形的每个点上种满树。
前面的数会挡住后面的树。
农夫能看见多少树。
这题就是连接农夫与任意一棵树,有多少种不同的斜率即能看到多少树,但是直接暴力做肯定超时。
如果(x,y)互质,即是新树,否则已经有过这棵树。
那么x从1-m 对于每一个x 寻找y在1-n之间又多少个与x互质的数。
这里用到容斥定理,寻找不互质的,总数相减。
例如2 2
1 2与1互质 斜率有1/1 2/1
1 与2互质 斜率有1/2
总数为3
#include<stdio.h> #include<string.h> int pr[444],num,id[444],a[1111]; __int64 x,y; __int64 ans; int cnt; void get_s() { memset(id,0,sizeof(id)); int i; num=0; int j; for(i=2;i<444;i++) { if(id[i]==0) { num++; pr[num]=i; } for(j=1;j<=num&&pr[j]*i<444;j++) { id[pr[j]*i]=1; if(i%pr[j]==0) break; } } } void dfs(int id,__int64 lcm,int num,__int64 x) { lcm=lcm*a[id]; //lcm是最小公倍数,因为是不同的质因数,直接相乘。 if(num&1) ans+=x/lcm; else ans-=x/lcm; for(int i=id+1;i<=cnt;i++) dfs(i,lcm,num+1,x); } int main() { __int64 d,putt; get_s(); int i,zz=1,j,k; int T,m; scanf("%d",&T); while(T--) { scanf("%I64d%I64d",&x,&y); if(x>y) { d=x; x=y; y=d; } putt=y; for(i=2;i<=x;i++) { d=i; cnt=0; ans=0; for(j=1;j<=num;j++) //获得质因数 { if(d==1) break; if(d%pr[j]==0) { cnt++; a[cnt]=pr[j]; while(d%pr[j]==0) d/=pr[j]; } } if(d!=1) { cnt++; a[cnt]=d; } for(k=1;k<=cnt;k++) dfs(k,1,1,y); ans=y-ans; //把ans从不互质的变成互质的 putt+=ans; } printf("%I64d\n",putt); } return 0; }