2020.11.23 考试题解
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\),即\(\left\lfloor\dfrac{b}{a}\right\rfloor=a\) 。显然,\(a\)小于\(\sqrt{n}\),直接等差数列\(O(1)\)就出即可,需特判一下\(\sqrt{n}\)。
<2>:
\(a>b\)时,\(\left\lfloor\dfrac{b}{a}\right\rfloor=0\)。
即为
\[\sum\limits_{a,b} {a\;mod\;b=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;
}

浙公网安备 33010602011771号