1. 程式人生 > >牛客國慶集訓派對Day5 L

牛客國慶集訓派對Day5 L

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld

題目描述

終於活成了自己討厭的樣子。 這是她們都還沒長大的時候發生的故事。那個時候,栗子米也不需要為了所謂的愛情苦惱。 她們可以在夏日的午後,花大把的時間去研究生活中一些瑣碎而有趣的事情,比如數論。 有一天西柚柚問了栗子米一個題,她想知道中有多少不同的數,這些不同的數字裡面第k大的是多少。

輸入描述:

第一行一個整數T(T≤ 105),表示資料組數。
每組資料第一行兩個整數,表示n,k(1≤ n≤ 1018),保證k不會超過不同的數字個數。

輸出描述:

對於每組資料輸出,輸出兩個整數,表示有多少個不同的數字和這裡面第k大的是多少。

示例1

輸入

複製

3
1 1
5 2
67 8

輸出

複製

1 1
3 2
15 8

(中文題就不寫題意了)

解析

數論題先打表

#include<bits/stdc++.h> #include<cstring> int const maxn=1e5; using namespace std; int func(int x){     int f=-1;     int cnt=0;     for(int i=1;i<=x;i++){         if(x/i!=f){             cout<<x/i<<' ';             cnt++;             f=x/i;         }     }     return cnt; }  int main(){     int t;     for(int i=1;i<=100;i++){         t=func(i);         cout<<endl;         cout<<i<<' '<<t<<'*'<<endl;     }  }

然後我們發現,個數m跟根號有關,然後是a=sqrt(n) 和 b=a+((a+1)*a<=n) ,m=a+b-1

我也不知道為什麼是這個規律,反正表上可知這個規律。而且最重要的是可以AC。QAQ

然後右邊一半是連續的,左邊一半是n/k

AC程式碼

#include<bits/stdc++.h> #include<cstring> using namespace std; typedef long long ll; signed main(){     int T;     cin>>T;     while(T--){         ll n,k;         scanf("%lld%lld",&n,&k);         ll sq1=sqrt(n);         ll sq2=sq1;         if(sq1*(sq2+1)<=n){             sq2++;         }         ll m=sq1+sq2-1;         if(k>m/2){             printf("%lld %lld\n",m,m-k+1);          }         else             printf("%lld %lld\n",m,n/k);      } }