CCPC-WannaFly-Camp #4 L数论之神

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tawn0000/article/details/81435913

数论之神

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 <iostream>
#include <cstdio>
#include <cmath>

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<int,int> 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
****************************************************************/

猜你喜欢

转载自blog.csdn.net/Tawn0000/article/details/81435913