2020.11.23 考試題解
阿新 • • 發佈:2020-12-04
T1
題目描述:
求滿足下列條件的二元組(a,b)的個數
a mod b = b div a
1<=a,b<=n
樣例輸入:
10
樣例輸出:
21
資料範圍:
對於 10%的資料: \(n\) <= \(10^3\)
對於 20%的資料: \(n\) <= \(10^5\)
對於 30%的資料: \(n\) <= \(10^7\)
對於 40%的資料: \(n\) <= \(10^{12}\)
當經過手模樣例和一些自己出的樣例之後,可以發現,\(a\)肯定不能等於\(b\),那麼就分為兩種情況討論:
<1>:
\(a<b\)時,\(a\;mod\;b=a\)
<2>:
\(a>b\)時,\(\left\lfloor\dfrac{b}{a}\right\rfloor=0\)。
即為
考慮轉換成列舉\(b\),即為
\[\sum\limits_{b} {(\left\lfloor\dfrac{n}{b}\right\rfloor-1)} \]減一是為了除去\(a=b\)
轉化之後即為 \[\sum\limits_{b} {\left\lfloor\dfrac{n}{b}\right\rfloor}-n \]
即為下底函式分塊,可將取值相同的一塊一起處理。
程式碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e7+7; #define il inline #define vocaloid(v) (v>='0'&&v<='9') #define ll long long template <typename T> il void read(T &x) { x=0;char v=getchar(); while(!vocaloid(v)) v=getchar(); while(vocaloid(v)) {x=(x<<1)+(x<<3)+v-'0';v=getchar();} } template <typename T> il void write(T x) { if(x>9) write(x/10); putchar(x%10+'0'); } bool flag=1; ll n,ans,a[5000007],cnt; int main() { freopen("diyiti.in","r",stdin); freopen("diyiti.out","w",stdout); read(n); ll mid=sqrt(n); for(int i=1;i<=mid;i++) a[++cnt]=i; int now=cnt; for(int i=now;i>=1;i--) a[++cnt]=n/a[i]; for(int i=1;i<=cnt;i++) ans+=(a[i]-a[i-1])*(n/a[i]); ans-=n; ans+=(mid-1)*mid/2-1; ans+=min(mid,n-mid*mid+1); write(ans);putchar('\n'); return 0; }