当前位置: 代码迷 >> 综合 >> 51nod 1352 集合计数 求解的个数
  详细解决方案

51nod 1352 集合计数 求解的个数

热度:94   发布时间:2024-01-15 06:27:03.0

1352 集合计数

  1. 1.0 秒
  2.  
  3. 131,072.0 KB
  4.  
  5. 20 分
  6.  
  7. 3级题

给出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个。


 收起

输入

第1行:1个整数T(1<=T<=50000),表示有多少组测试数据。
第2 - T+1行:每行三个整数N,A,B(1<=N,A,B<=2147483647)

输出

对于每组测试数据输出一个数表示满足条件的集合的数量,占一行。

输入样例

2
5 2 4
10 2 3

输出样例

1
2

 

分析:

问题可以变成:Ax+By=n+1,然后扩展欧几里德可以求出最小解x0,最大解y0

然后对于最大的数By0减少一个lcm(A,B)就会出现一个答案(因为既要顾及a,又要顾及b),所以By0/lcm(A,B)就为最后的答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;LL exgcd(LL a, LL b, LL &x0, LL &y0)
{if(!b){x0 = 1; y0 = 0;return a;}int ans=exgcd(b, a%b, x0, y0);int t = x0;x0 = y0;y0 = t-a/b*y0;return ans;
}int main()
{LL n,a,b;int T;cin>>T;while(T--){scanf("%lld%lld%lld",&n,&a,&b);LL x0,y0;LL c=n+1;         //ax+by=c 的解LL gcd=exgcd(a,b,x0,y0);LL lcm=a/gcd*b;if(c%gcd)  printf("0\n");else {LL t=b/gcd;x0*=c/gcd;x0=(x0%t+t)%t;//cout<<x0<<endl;while(x0<=0) x0+=t;//最小的正整数解x  LL By=c-x0*a;//s为b*y if(By<=0)cout<<"0"<<endl;else{//cout<<(n-a*x0)/lcm+1<<endl;if(By%a)cout<<1+By/lcm<<endl;elsecout<<By/lcm<<endl;   }}}return 0;
}