为防止广告,目前nocow只有登录用户能够创建新页面。如要创建页面请先登录/注册(新用户需要等待1个小时才能正常使用该功能)。

Sgu/106

来自NOCOW
< Sgu
跳转到: 导航, 搜索

扩展欧几里得...线性不定方程+不等式求解,特殊情况考虑 1.a=0 b=0; 2.a=0 b<>0; 3.a<>0 b=0.

Program The_equation;
Const
	inp='input.txt';
	oup='output.txt';
Var
	a,b,c,x1,x2,y1,y2,h,d,x0,y0:int64;
	tu,td,temp:extended;
Function extend_gcd(a,b:int64; var x,y:int64):int64;
	begin
		if b=0 then
			begin
				x:=1; y:=0; extend_gcd:=a; exit;
			end;
		extend_gcd:=extend_gcd(b,a mod b,y,x);
		y:=y-(a div b)*x;
	end;
 
Begin
	assign(input,inp); reset(input);
	assign(output,oup); rewrite(output);
	read(a,b,c,x1,x2,y1,y2);
	c:=-c;
	if c<0 then
		begin
			a:=-a; b:=-b; c:=-c;
		end;
	if a<0 then
		begin
			a:=-a; x1:=-x1; x2:=-x2; h:=x1; x1:=x2; x2:=h;
		end;
	if b<0 then
		begin
			b:=-b; y1:=-y1; y2:=-y2; h:=y1; y1:=y2; y2:=h;
		end;
	if (a=0) and (b=0) then
		if c=0 then writeln((x2-x1+1)*(y2-y1+1)) else writeln(0)
	else if a=0 then
		if c mod b<>0 then writeln(0)
		else begin
			c:=c div b;
			if (c>=y1) and (c<=y2) then writeln(x2-x1+1) else writeln(0);
		end
	else if b=0 then
		if c mod a<>0 then writeln(0)
		else begin
			c:=c div a;
			if (c>=x1) and (c<=x2) then writeln(y2-y1+1) else writeln(0);
		end
	else begin
		d:=extend_gcd(a,b,x0,y0);
		if c mod d<>0 then writeln(0)
		else begin
			a:=a div d; b:=b div d; c:=c div d;
			extend_gcd(a,b,x0,y0);
			td:=(x1-c*x0)/b; tu:=(x2-c*x0)/b;
			temp:=(c*y0-y2)/a; if temp>td then td:=temp;
			temp:=(c*y0-y1)/a; if temp<tu then tu:=temp;
			if tu<td then writeln(0)
			else begin
				x1:=trunc(td)-3;
				while x1<td do inc(x1);
				x2:=trunc(tu)+3;
				while x2>tu do dec(x2);
				writeln(x2-x1+1);
			end;
		end;
	end;
	close(input); close(output);
End.


//by abccbazj
#include <cstdio>
long long a,b,c;
long long x1,x2,y1,y2;
long long cnt;
void swap(long long &x,long long &y){
     long long t=x;
     x=y;
     y=t;
}
long long Exgcd(long long a,long long b,long long &x,long long &y){
    if (b==0){
              x=1;
              y=0;
              return a;
    }
    long long d=Exgcd(b,a % b,x,y);
    long long t=x;
    x=y;
    y=t-(a/b)*y;
    return d;
}
int main(){
    scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&x1,&x2,&y1,&y2);
    c=-c;
    if (a==0 && b==0){
             if (c==0){
                       cnt=(x2-x1+1)*(y2-y1+1);
             }
    }else if (a==0){
          if (c % b==0 && c/b>=y1 && c/b<=y2){
                cnt=x2-x1+1;
          }
    }else if (b==0){
          if (c % a==0 && c/a>=x1 && c/a<=x2){
                cnt=y2-y1+1;
          }
    }else{
          long long x=0,y=0;
          long long d=Exgcd(a,b,x,y);
          if (c % d==0){
             long long tx=x*(c/d);
             long long ty=y*(c/d);
             long long lx,ly,rx,ry;
             lx=(x1<=tx || (x1-tx)*d % b==0) ? (x1-tx)*d/b : (x1-tx)*d/b+1;
             rx=(x2>=tx || (tx-x2)*d % b==0) ? (x2-tx)*d/b : (x2-tx)*d/b-1;
             ly=(y1<=ty || (y1-ty)*d % a==0) ? (ty-y1)*d/a : (ty-y1)*d/a-1;
             ry=(y2>=ty || (ty-y2)*d % a==0) ? (ty-y2)*d/a : (ty-y2)*d/a+1;
             if (lx>rx) swap(lx,rx);
             if (ly>ry) swap(ly,ry);
             if (lx<=ry && ly<=rx){
                        long long max=(lx>ly)?lx:ly;
                        long long min=(rx<ry)?rx:ry;
                        cnt=min-max+1;
             }
          }
    }
    printf("%I64d\n",cnt);
    return 0;
}
个人工具