牛客國慶集訓派對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); } }