简单题,先二分出直线上 $x$ 最小的点使得这个点在矩形内。
然后不断跳,直到遇到整点。(实际上要用扩欧,但初测能过于是就偷个懒没写)
接着不断跳直到不符合条件。
先 $\sqrt{V}$ 个跳一下,跳完后再一个一个跳就不用写二分了多好。
代码:
#include<iostream> #define int long long using namespace std; double a,b,c,k; double x1,x2,y1,y2; int gcd(int a,int b){ if(b==0)return a; return gcd(b,a%b); } double check(int mid){return (-a*mid-c)/b;} //-a*x%b==c signed main(){ cin>>a>>b>>c>>x1>>x2>>y1>>y2; //b/gcd(a,b); int l=x1,r=x2,mid; if((a>0)^(b>0))k=1; else k=-1; while(l<=r){ mid=l+r>>1; double y=check(mid); if(y<y1){ if(k==-1)r=mid-1; else l=mid+1; }else if(y>y2){ if(k==-1)l=mid+1; else r=mid-1; }else r=mid-1; } double y=-a/b*(r+1)-c/b; if(y<y1||y>y2){ cout<<0; return 0; } int ans=r+1,sum=0,d=(int)(b)/gcd(a,b); while((int)(-a*ans-c)%(int)b!=0)++ans; if(ans<x1)ans+=d; if(ans>x2){ cout<<0; return 0; } sum=1; int t=(int)(b)/gcd(a,b); if(t<0)t=-t; while(ans+31622*t<=x2&&ans+31622*t>=x1&&check(ans+31622*t)>=y1&&check(ans+31622*t)<=y2){ ans+=31622*t; sum+=31622; } while(ans+t<=x2&&ans+t>=x1&&check(ans+t)>=y1&&check(ans+t)<=y2){ ans+=t; ++sum; } cout<<sum; return 0; }
标签:YACS,int,题解,ans,mid,甲组,double,x1,check From: https://www.cnblogs.com/Xy-top/p/17660110.html