12.1 题目描述
终于活成了自己讨厌的样子。
这是她们都还没长大的时候发生的故事。那个时候,栗子米也不需要为了所谓的爱情苦恼。
她们可以在夏日的午后,花大把的时间去研究生活中一些琐碎而有趣的事情,比如数论。
有一天西柚柚问了栗子米一个题,她想知道 ⌊n/1⌋, ⌊n/2⌋, . . . , ⌊n/n⌋ 中有多少不同的数这些不同的数字里面第 k 大的是多少。
12.2
输入格式
第一行一个整数 T(T ≤ 105),表示数据组数。
每组数据第一行两个整数,表示 n, k(1 ≤ n ≤ 1018),保证 k 不会超过不同的数字个数。
12.3
输出格式
对于每组数据输出,输出两个整数,表示有多少个不同的数字和这里面第 k 大的是多少。
12.4 样例输入
3
1 1
5 2
67 8
12.5 样例输出
1 1
3 2
15 8
结论
错误点:
1.sqrt(LL) 有效位只有15·16位精度不够,可以采用二分或者左右查找解决
2.第K大,是指从大的开始往前数数数数数数数数数数数。。。。。。。。。。
(RE到怀疑人生~~~~)
3.如果t = n^(1/2), 则 t*(t+1) > n 等价于 n/t == t;
例如 n为 16 - 24 中的数 t = 4,那么满足 n/t == t 为16 - 19 正好位 t*(t+1) > n的n的范围
用此等价式可以解决相乘超longlong 的情况
#include
#include
#include
using namespace std;
#define PI 3.1415926
#define sc(a) scanf("%d",&a)
#define pfs(a) printf("%d ",a)
#define pfn(a) printf("%d\n",a);
#define pfln(a) printf("%lld\n",a);
#define rep(n) for(int i = 0; i < n; i++)
#define per(n) for(int i = m-1; i >= 0; i--)
#define mem(a,x) memset(a,x,sizeof(a))
typedef long long LL;
typedef pair P;
const int maxn = 1000+100;
const int mod = 1e9+7;
const int INF = 1e9+1;
void solve (){
LL n,k;
scanf ("%lld %lld",&n,&k);
LL t = (LL)sqrt(n);
while((t+1)*(t+1) <= n) t++;
while(t*t > n) t--;
LL ans1,ans2;
if(t*(t+1) <= n) ans1 = 2*t;
else ans1 = 2*t-1;
k = ans1-k+1;
if(k <= t) ans2 = k;
else ans2 = n/(ans1-k+1);
printf("%lld %lld\n",ans1,ans2);
}
int main()
{
int T;
sc(T);
while(T--)solve();
return 0;
}
/**************************************************************
Problem: 1081
User: 1061
Language: C++
Result: Accepted
Time:172 ms
Memory:1552 kb
****************************************************************/