wannafly camp day4 数论

2098: 数论之神

描述

题目描述:

终于活成了自己讨厌的样子。

这是她们都还没长大的时候发生的故事。那个时候,栗子米也不需要为了所谓的爱情苦恼。

她们可以在夏日的午后,花大把的时间去研究生活中一些琐碎而有趣的事情,比如数论。

有一天西柚柚问了栗子米一个题,她想知道⌊n1⌋,⌊n2⌋,…,⌊nn⌋\lfloor\frac{n}{1}\rfloor, \lfloor\frac{n}{2}\rfloor, \dots, \lfloor\frac{n}{n}\rfloor1n,2n,,nn⌋中有多少不同的数,这些不同的数字里面第kkk大的是多少。

输入:

第一行一个整数T(T≤105)T(T\leq 10^5)T(T105),表示数据组数。

每组数据第一行两个整数,表示n,k(1≤n≤1018)n,k(1\leq n\leq 10^{18})n,k(1n1018),保证kkk不会超过不同的数字个数。

输出:

对于每组数据输出,输出两个整数,表示有多少个不同的数字和这里面第k大的是多少。

样例输入
3
1 1
5 2
67 8
样例输出
1 1
3 2
15 8

题目分析 : 找规律发现一定是1, 2, 3, ..., x, n/(x-1), n/(x-2), .... x是sqrt(n)附近
代码示例 :
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
#define ll long long
 
ll n, k;
ll ff;

int main() {
    ll t;
     
    cin >> t;
    while(t--){ 
    	scanf("%lld%lld", &n, &k);
		ll f;
        ll l = 1, r = 1000000000;
        while(l <= r){
            ll mid = (l+r)>>1;
            if (mid*mid <= n) {
                f = mid;
                l = mid+1;
            }
            else r = mid-1;
        }
		ll ans = 2*f;
		if (f == n/f) ans--;
        
        ll ans2;
        ll k1 = ans-k+1; // 第 K 小
        if(k1 <= f)  ans2 = k1;
        else ans2 = n/k;
        printf("%lld %lld\n", ans, ans2);
    }
     
    return 0;
}



猜你喜欢

转载自www.cnblogs.com/ccut-ry/p/9441907.html