LOJ 6714 Stupid Product
LOJ 6714 Stupid Product
定义一个序列为 \(\prod_{i} a_i(a_i>1)\),空序列的权值为 \(1\)
记权值为 \(x\) 的序列个数为 \(f(x)\)
给定 \(n\),求 \(\sum^n f(x)\)
\(n\le 10^{10}\),答案对 \(998244353\) 取模。
Solution
不难发现 \(f(1)=1,f(x)=\sum_{d|x,d\ne x} f(d)\)
考虑迪利克雷卷积意义下的 \(f\cdot I\),有:
对于 \(x=1,f\cdot I(1)=1\)
对于 \(x\ne 1,f\cdot I(x)=2f(x)\)
对于 \(S(n)=\sum_{i=1}^n f(i)\) 考虑
\[2S(n)-1=\sum_{i=1}^{n}\sum_{j|i}f(j)
\]
\[2S(n)-1=\sum_{j=1}^n \sum_{k\le \frac{n}{j}} f(k)
\]
\[2S(n)-1=\sum_{j=1}^n S(\Big\lfloor\frac{n}{j}\Big\rfloor)
\]
\[S(n)=1+\sum_{j=2}^n S(\Big\lfloor\frac{n}{j}\Big\rfloor)
\]
直接递归就很对?复杂度 \(\mathcal O(n^{\frac{3}{4}})\)。
如果常数不好就会被卡掉,要写 \(\mathcal O(n^{\frac{2}{3}}\log^{w} n)\) 之类的东西,不过我把取模删了就过了。
\(Code:\)
#include<bits/stdc++.h>
using namespace std ;
#define int long long
int gi() {
char cc = getchar() ; int cn = 0, flus = 1 ;
while( cc < '0' || cc > '9' ) { if( cc == '-' ) flus = - flus ; cc = getchar() ; }
while( cc >= '0' && cc <= '9' ) cn = cn * 10 + cc - '0', cc = getchar() ;
return cn * flus ;
}
const int P = 998244353 ;
const int M = 3e5 + 5 ;
int n, lim, st[M], top, f1[M], f2[M] ;
int S(int x) { return ( x <= lim ) ? f1[x] : f2[n / x] ; }
signed main()
{
n = gi(), lim = sqrt(n) + 1 ;
for(int l = 1, r; l <= n; l = r + 1)
r = (n / (n / l)), st[++ top] = n / l ;
f1[1] = 1 ;
for(int i = top - 1; i >= 1; -- i) {
int x = st[i], ans = 1 ;
for(int l = 2, r; l <= x; l = r + 1) {
r = (x / (x / l)) ;
ans = (ans + (r - l + 1) * S(x / l)) ;
} ans %= P ;
if( x <= lim ) f1[x] = ans ;
else f2[n / x] = ans ;
}
cout << f2[1] << endl ;
return 0 ;
}