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

 

posted @ 2019-06-09 21:07  LuitaryiJack  阅读(151)  评论(0编辑  收藏  举报