解的个数(扩展欧几里得解不定方程)
解的个数
题目描述:
已知整数x,y满足如下面的条件:
ax+by+c = 0
p<=x<=q
r<=y<=s
求满足这些条件的x,y的个数。
输入描述:
第一行有一个整数n(n<=10),表示有n个任务。n<=10
以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。
输出描述:
共n行,第i行是第i个任务的解的个数。
样例输入:
2
2 3 -7 0 10 0 10
1 1 1 -10 10 -9 9
样例输出:
1
19
#include<iostream>
#include<cstdio>
#define lon long long
using namespace std;
int t,x,y,g,ans;
int a,b,c,l1,l2,r1,r2;
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=ex_gcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return r;
}
int main()
{
scanf("%d",&t);
while(t--)
{
ans=0;
scanf("%d%d%d%d%d%d%d",&a,&b,&c,&l1,&r1,&l2,&r2);
c=-c;
if(a==0&&b==0)
{
if(c!=0||l1>r1||l2>r1)
{
printf("0\n");
continue;
}
long long t1=r1-l1+1,t2=r2-l2+1;
long long t3=t1*t2;
cout<<t3;
printf("\n");
continue;
}
if(a==0)
{
y=c/b;
if(y<l2||y>r2||c%b!=0)
printf("0\n");
else printf("1\n");
continue;
}
if(b==0)
{
x=c/a;
if(x<l1||x>r1||c%a!=0)
printf("0\n");
else printf("1\n");
continue;
}
g=ex_gcd(a,b,x,y);
if(c%g!=0)
{
printf("0\n");
continue;
}
int s=c/g;
x=x*s,y=y*s;
int ta=a/g,tb=b/g;
if(x<l1)
{
while(x<l1) x+=tb,y-=ta;
for(int i=x;i<=r1;i+=tb,y-=ta)
if(y>=l2&&y<=r2) ans++;
}
else if(x>r1)
{
while(x>r1) x-=tb,y+=ta;
for(int i=x;i>=l1;i-=tb,y+=ta)
if(y>=l2&&y<=r2) ans++;
}
else
{
int ty=y;
for(int i=x;i<=r1;i+=tb,ty-=ta)
if(ty>=l2&&ty<=r2) ans++;
ty=y+ta;
for(int i=x-tb;i>=l1;i-=tb,ty+=ta)
if(ty>=l2&&ty<=r2) ans++;
}
cout<<ans; printf("\n");
}
return 0;
}