专栏文章
题解:AT_abc414_e [ABC414E] Count A%B=C
AT_abc414_e题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miowtkq6
- 此快照首次捕获于
- 2025/12/03 02:26 3 个月前
- 此快照最后确认于
- 2025/12/03 02:26 3 个月前
解题思路
由于余数 于 密切相关,且当 一定时, 是唯一的,确定的。因此在统计答案是不需要枚举 。
为了防止数对重复,我们规定:。
再由题面知,,即 不能为 ,也就是 不能是 的倍数的情况都成立。所以我们只要知道 ()的所有可能对数 和 中 ( 能整除 ,)的对数 。最终答案就是 。
解释一下上面为什么 可以与 相等:是因为当 时, 成立所以它在 和 里都统计了一次,在最终答案里抵消了相当于没统计,所以上面的 可以与 相等。
的计算十分简单,因为在 时有 个数对,所以 。 时间复杂度 。
但是 就比较难在 1s 计算了,它的计算需要使用“数论分块”算法。在此,我就不献丑介绍了。不会的同学可以学习 P3935 Calculating 及其题解,它告诉了我们,如何在 的时间里求出 到 内的约数个数和。
代码如下:
CPPfor(int l=1,r;l<=N;l=r+1){
r=N/(N/l);
ans+=(N/r)%mod*((r-l+1)%mod)%mod;
ans%=mod;
}
最后只要注意取模并统计答案就行了。
时间复杂度:。
赛时代码
代码很短,不含注释只有 300 多 Byte。
CPP#include<bits/stdc++.h>
#define int long long//记得开long long
using namespace std;
const int mod=998244353;//记得取模
int N,ans;
signed main(){
cin>>N;
for(int l=1,r;l<=N;l=r+1){//统计约数对数
r=N/(N/l);
ans+=(N/r)%mod*((r-l+1)%mod)%mod;
ans%=mod;
}
int sum;//统计所有可能对数
if(N%2) sum=(N+1)/2%mod*(N%mod)%mod;
else sum=N/2%mod*((N+1)%mod)%mod;
cout<<(sum-ans+mod)%mod;//输出答案
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...