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 }

 

posted @ 2018-09-02 12:57  starry_sky  阅读(233)  评论(0编辑  收藏  举报