未完全弄懂的題的題51nod1532
阿新 • • 發佈:2018-04-19
gcd inpu unsigned namespace roc n-1 http mem csdn
轉載自:https://blog.csdn.net/luricheng/article/details/52752094
1352 集合計數
基準時間限制:1 秒 空間限制:131072 KB 分值: 20 難度: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個。
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
問題其實就是求滿足
ax+by=n+1 //①
1<=x<=n/a //②
1<=y<=n/b //③
的{x,y}的對數
令:
d=gcd(a,b)
lcm=(x,y)的最小公倍數
x‘=x*(n+1)/d
y‘=y*(n+1)/d
則:
ax‘+by‘= n+1
t1=lcm/a
t2=lcm/b
顯然:
a(x‘+k*t1) + b(y‘-k*t2)=n+1
a(x‘-k*t1) + b(y‘+k*t2)=n+1 k=0,1,2...
只要找到第一對滿足①②③的x,y 然後根據Lcm就可以找到一共有多少對
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
#define pll pair<ll,ll>
#define pid pair<int,double>
//#define CHECK_TIME
int extend_gcd(ll a,ll b,ll&x,ll&y){
if(!b){
x=1;
y=0;
return a;
}
ll xt=0,yt=0;
int d=extend_gcd(b,a%b,xt,yt);
x=yt;
y=xt-yt*(a/b);
return d;
}
int main()
{
int T;
scanf("%d",&T);
ll n,a,b,x,y,d,lcm,t1,t2;
while(T--){
scanf("%lld%lld%lld",&n,&a,&b);
d=extend_gcd(a,b,x,y);
if((n+1)%d!=0){
printf("0\n");
continue;
}
x*=(n+1)/d,y*=(n+1)/d;
lcm=a/d*b;
t1=lcm/a,t2=lcm/b;
if(x<1){
ll num=(1-x)/t1;
x+=num*t1;
y-=num*t2;
if(x<1){
y-=t2;
x+=t1;
}
}
if(y<1){
ll num=(1-y)/t2;
y+=num*t2;
x-=num*t1;
if(y<1){
y+=t2;
x-=t1;
}
}
int ans=x>0&&y>0;
if(ans){
ans+=min((x-1)/t1,(n/b-y)/t2);
ans+=min((y-1)/t2,(n/a-x)/t1);
}
printf("%d\n",ans);
}
return 0;
}
未完全弄懂的題的題51nod1532