51nod 1352 集合计数
给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数。
提示:
对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个。
Input
第1行:1个整数T(1<=T<=50000),表示有多少组测试数据。 第2 - T+1行:每行三个整数N,A,B(1<=N,A,B<=2147483647)
Output
对于每组测试数据输出一个数表示满足条件的集合的数量,占一行。
Input示例
2 5 2 4 10 2 3
Output示例
1 2
求有多少个{x,Y} > 0 使的 A*X+B*Y = n+1,扩展欧几里得,先求的一个A*X+B*Y = n+1 使X最小Y最大,然后计算。
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 5 void exgcd(ll a, ll b,ll &d, ll &x, ll &y) { 6 if(!b){ 7 d = a; 8 x = 1; y = 0; 9 }else{ 10 exgcd(b, a%b, d, y, x); 11 y -= x*(a/b); 12 } 13 } 14 15 int main() { 16 int t; 17 scanf("%d", &t); 18 while(t--) { 19 ll a, b, x, y, n, d; 20 scanf("%lld%lld%lld",&n,&a,&b); 21 exgcd(a,b,d,x,y); 22 n++; 23 if(n%d) { 24 printf("0\n"); 25 continue; 26 } 27 a /= d; b /= d; 28 x *= n/d; y *= n/d; 29 ll xx = (x-(x/b)*b); 30 ll yy = (y+(x/b)*a); 31 if(xx <= 0) xx += b, yy -= a; 32 // printf("%lld %lld\n",xx,yy ); 33 if(xx > n || yy <= 0) printf("0\n"); 34 else printf("%lld\n",min((n-xx)/b+((n-xx)%b?1:0),yy/a+((yy%a)?1:0))); 35 } 36 return 0; 37 }