专栏文章
传奇模数 题解
P13679题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miodzfot
- 此快照首次捕获于
- 2025/12/02 17:39 3 个月前
- 此快照最后确认于
- 2025/12/02 17:39 3 个月前
1.题意
同官方题解,在这里我们定义 。
对于正整数 ,求 。
2.我会暴力
只得赛后打个代码给各位献丑:
CPP#include <bits/stdc++.h>
#define int long long
using namespace std ;
int n , ans ;
const int p = 998244353 ;
signed main () {
cin >> n ;
for (int i = p ; i <= n ; i ++) {
ans += i / p ;
ans %= p ;
}
cout << ans % p ;
}
竟然优化后有 40 pts!
3.转向规律
既然暴力不行,那就找找规律。
我们注意到:
- 若 ,显然 。
- 若 ,显然 。
- 若 ,显然 。
- 满足 为正整数,若 ,显然 。
所以,不必要一一枚举,只需每次加上 就行了,或者枚举到 ,只要最后再末尾判断一次就行了。
赛时代码加了些注释,由于太紧张,码风不太好,见谅:
CPP#include <bits/stdc++.h>
using namespace std ;
#define int long long
const int mod = 998244353 ;
int n , ans ;
signed main () {
ios::sync_with_stdio (false) ;
cin.tie (NULL) ; cout.tie (NULL) ;
cin >> n ;
int x = n / 998244353 ;
int y = n % 998244353 ;
for (int i = 0 ; i < x ; i ++) { // 枚举到 <x,最后尾判。
ans += i * 998244353 ; //从 kp 到 (k+1)p 共有 p(在这里是 mod) 个。
ans %= mod ;
}
ans += (y + 1) * x ; //尾判,显然最后有 y+1 个 k=x。
cout << ans % mod ;
return 0 ;
}
上交一测,结果:

怎么回事?
4.数学优化
令 ,下面代码:
CPPfor (int i = 0 ; i < x ; i ++) {
ans += i * p ;
ans %= mod ;
}
不难看出:,再进行一些一些操作:
根据小学二年级就学过的等差数列求和公式 ( 为数列的个数),可知:,这样复杂度就降为 了,十分优秀,妈妈再也不会担心我过不了了!
放上赛时稍加修改的代码:
CPP#include <bits/stdc++.h>
using namespace std ;
#define int long long
const int p = 998244353 ;
int n , ans ;
signed main () {
ios::sync_with_stdio (false) ;
cin.tie (NULL) ; cout.tie (NULL) ;
cin >> n ;
int x = n / 998244353 ;
int y = n % 998244353 ;
ans += x % p * (x - 1) % p * p % p / 2 % p ;
/*1+x+..+(x-1)=(1+x-1)*(x-1)/2*/
ans += (y + 1) * x ;
cout << ans % p ;
return 0 ;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...