程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> hdu3388Coprime 二分+容斥原理

hdu3388Coprime 二分+容斥原理

編輯:關於C++
//找第k個和n,m互質的數
//由容斥原理可得
//在[1,x]范圍內且與n不互質的數的個數為:
//對於所有的n的素數因子:和一個素數因子不互質的個數-兩個素數因子相乘的個數+三個素數因子相乘的個數-.....
//對於x越大,在[1 , x]范圍內的與n,m互質的數越多,所以存在單調性,可以用二分找到剛好有k個數和n,m互質
#include
#include
#include
#include
using namespace std ;
typedef __int64 ll ;
const int maxn = 100010 ;
const int inf = 1e9 ;
mapma ;
ll p[maxn] ;
int len ;
void getprime(ll n)
{
for(int i = 2;i*i <= n;i++)
{
if(n%i == 0 && !ma[i])
{
p[++len] = i ;
ma[i] = 1;
}
while(n%i == 0)n/=(ll)i ;
}
if(n > 1 && !ma[n]){p[++len] = n;ma[n]=1;}
}
ll dfs(int pos , ll n)
{
ll ans = 0 ;
for(int i = pos ;i <= len ;i++)
ans += n/p[i] - dfs(i+1 , n/p[i]) ;
return ans ;
}
ll find(ll l , ll r , ll num )
{
while(l <= r)
{
ll mid = (l+r) >> 1 ;
if((mid - dfs(1 , mid)) < num)
l = mid + 1 ;
else r = mid - 1;
}
return l ;
}
int main()
{
// freopen("in.txt","r",stdin) ;
// freopen("out.txt","w" ,stdout) ;
int T ;int cas = 0 ;
int n , m ;int k ;
scanf("%d" , &T) ;
while(T--)
{
scanf("%d%d%d" ,&n , &m , &k) ;
len = 0 ;
ma.clear() ;
getprime((ll)(n));
getprime((ll)(m));
ll ans = find(1 , (ll)inf*(ll)inf, (ll)k);
printf("Case %d: " , ++cas) ;
printf("%I64d\n" , ans) ;
}
return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved