codevs 1213 解的个数
题目描述 Description
已知整数x,y满足如下面的条件:
ax+by+c = 0
p<=x<=q
r<=y<=s
求满足这些条件的x,y的个数。
输入描述 Input Description
第一行有一个整数n(n<=10),表示有n个任务。n<=10
以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。
输出描述 Output Description
共n行,第i行是第i个任务的解的个数。
样例输入 Sample Input
2
2 3 -7 0 10 0 10
1 1 1 -10 10 -9 9
样例输出 Sample Output
1
19
思路:
扩展欧几里得,特判是一次函数的情况。
代码:
#include<cstdio> #include<algorithm> #include<iostream> #define ll long long using namespace std; ll n,a,b,c,p,q,r,s,ans; void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1; y=0; return ; } exgcd(b,a%b,y,x); y-=x*(a/b); } void slove() { int t=__gcd(a,b); c*=-1; if(!a&&!b) { if(c||p>q||r>s) printf("0\n"); else printf("%lld\n",(q-p+1)*(s-r+1)); return ; } if(!a) { ll d=c/b; if(d>=r&&d<=s&&!(c%b)) printf("1\n"); else printf("0\n"); return ; } if(!b) { ll d=c/a; if(d>=p&&d<=q&&!(c%a)) printf("1\n"); else printf("0\n"); return ; } if(c%t) { printf("0\n"); return ; } ll x=0,y=0; ans=0; exgcd(a,b,x,y); x=x*c/t; y=y*c/t; a/=t,b/=t; int e=0; if(x<p) { while(x+e*b<p) e++; while(x+e*b<q) { if(r<=y-e*a&&y-e*a<=s) ans++; e++; } } else if(x>q) { while(x-e*b>q) e++; while(x-e*b>p) { if(r<=y+e*a&&y+e*a<=s) ans++; e++; } } else if(x>=p&&x<=q) { while(x+e*b<=q) { if(r<=y-e*a&&y-e*a<=s) ans++; e++; } e=-1; while(x+e*b>=p) { if(r<=y-e*a&&y-e*a<=s) ans++; e--; } } printf("%lld\n",ans); } int main() { int i,j; cin>>n; while(n--) { cin>>a>>b>>c>>p>>q>>r>>s; slove(); } return 0; }