Luogu P2833 等式 我是傻子x2
又因为调一道水题而浪费时间。。。不过细节太多了$qwq$,暴露出自己代码能力的不足$QAQ$
设$d=gcd(a,b)$,这题不是显然先解出来特解,即解出
$\frac{a}{d}x_0+\frac{b}{d}y_0=d$,中的$x_0,y_0$
然后根据
$x=\frac{c}{d}x_0+k\frac{b}{d},y=\frac{c}{d}x_0-k\frac{a}{d},k \in Z$
来卡范围吗$qwq$
然后自己就兴致勃勃的调了一晚上,老是差一点。。。后来发现一个大细节,就是左右端点,左端点要向上取整,右端点要向下取整$qwq$,发现后又调了半天$qwq$
对了还有一堆特判。。。主要是判各种$0$的,什么$a=0,b=0,c=0$之类的。。。详见代码
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<vector> #include<queue> #include<map> #include<set> #define ll long long #define int ll #define R register ll using namespace std; namespace Fread { static char B[1<<15],*S=B,*D=B; #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } }using Fread::g; inline void exgcd(ll a,ll b,ll& x,ll& y) {if(!b) {x=1,y=0; return ;} exgcd(b,a%b,y,x); y-=a/b*x;} inline ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} int a,b,c,x1,x2,Y1,Y2; signed main() { #ifdef JACK freopen("NOIPAK++.in","r",stdin); #endif a=g(),b=g(),c=-g(),x1=g(),x2=g(),Y1=g(),Y2=g(); R d=gcd(a,b); if(a==0&&b==0) { if(c!=0) {printf("0\n"); return 0;} else if(c==0) {R k=(ll)(x2-x1+1)*(Y2-Y1+1); printf("%lld\n",k); return 0;} } if(c%d!=0) {printf("0\n"); return 0;} R x,y; exgcd(a,b,x,y); if(a==0||b==0) { if(a==0) { Y1>Y2?swap(Y1,Y2):void(0); y=y*c/d; if(y>=Y1&&y<=Y2) printf("%lld\n",x2-x1+1); else printf("0\n"); } else if(b==0) { x1>x2?swap(x1,x2):void(0); x=x*c/d; if(x>=x1&&x<=x2) printf("%lld\n",Y2-Y1+1); else printf("0\n"); } return 0; } x1-=x*c/d,x2-=x*c/d,Y1-=y*c/d,Y2-=y*c/d; if(!(x1<x2)^(b>=0)^(d>=0)) swap(x1,x2); if((Y1<Y2)^(a>=0)^(d>=0)) swap(Y1,Y2); R k1=(x1+b-1)/b*d,k2=(x2-b+1)/b*d,k3=(-Y1*d+a-1)/a,k4=(-Y2*d-a+1)/a; k1=(ll)ceil((long double)x1*d/b),k2=(ll)floor((long double)x2*d/b),k3=(ll)ceil((long double)-Y1*d/a),k4=(ll)floor((long double)-Y2*d/a); if(k1>k2) swap(k1,k2); if(k3>k4) swap(k3,k4); R kn=max(k1,k3),kx=min(k2,k4); if(kx-kn<0) printf("0\n");else printf("%lld\n",kx-kn+1); }
2019.06.09