题目
题目描述 从
[
2
,
n
]
[2,n]
[2,n] 中选出若干质数,记这些质数的集合为
P
P
P 。定义集合
S
P
=
{
k
x
??
∣
??
x
∈
P
,
??
k
∈
N
+
,
??
k
?
?
n
x
?
}
S_P=\{kx\;|\;x\in P,\;k\in\N^+,\;k\leqslant\lfloor{n\over x}\rfloor\}
SP?={kx∣x∈P,k∈N+,k??xn??},即这些质数的倍数(不超过
n
n
n 的)。
记
f
(
S
)
f(S)
f(S) 为,从集合
S
S
S 中能选出的最多的数字个数,使得这些数字之间不存在倍数关系。现在请你求出
∑
P
f
(
S
P
)
\sum_{P}f(S_P)
∑P?f(SP?),即对于所有可能的
P
P
P 求出
f
(
S
P
)
f(S_P)
f(SP?) 的和。答案对
998244353
998244353
998244353 取模。
数据范围与提示
n
?
1
0
10
n\leqslant 10^{10}
n?1010 。
思路
看题解,感觉是推导出来的,结果最后还是落脚到归纳法上了。我讨厌归纳法。
不如直接放结论:选择大于
?
n
2
?
\lfloor{n\over 2}\rfloor
?2n?? 的所有可选数字。该方案显然合法,且不超过
?
n
2
?
\lfloor{n\over 2}\rfloor
?2n?? 的可选数字必然存在大于
?
n
2
?
\lfloor{n\over 2}\rfloor
?2n?? 的倍数,故肯定不可选。下证充分性。
调整法。若选择的最小数
y
?
?
n
2
?
y\leqslant\lfloor{n\over 2}\rfloor
y??2n??,尝试将其改为
2
y
2y
2y 。若其因此成为另一数
z
z
z 的倍数,即
z
∣
2
y
z\mid 2y
z∣2y,由前提
z
?
y
z\nmid y
z?y,故必然有
2
∣
z
2\mid z
2∣z 且
z
2
∣
y
\frac{z}{2}\mid y
2z?∣y 。又由假设
z
>
y
z>y
z>y 即
z
2
>
y
2
{z\over 2}>\frac{y}{2}
2z?>2y? 为最小(可能的)真因子,所以唯一解是
z
2
=
y
\frac{z}{2}=y
2z?=y,与
y
,
z
y,z
y,z 可以被同时选择矛盾。
当然,也可以看看题解的说法:若
i
∣
j
i\mid j
i∣j 连边
i
→
j
i\to j
i→j,问题为最长反链长度
=
=
= 最小链覆盖。结论是,找到最小没被覆盖的数
x
x
x,然后覆盖
2
k
x
??
(
k
∈
N
)
2^kx\;(k\in\N)
2kx(k∈N) 。结论的证明是,归纳法可知
2
x
2x
2x 未被覆盖,此时若不覆盖
2
x
2x
2x 以后还会需要一条链。
我比较好奇的是,怎么归纳的?而且
2
x
2x
2x 确定要选了,那
4
x
,
8
x
,
16
x
4x,8x,16x
4x,8x,16x 呢?😵
别管那么多了,还是回到结论上。对每个数字算贡献,即求
x
x
x 何时可选。记
c
(
x
)
c(x)
c(x) 为
x
x
x 的质因子个数,则只要任一质因子在
P
P
P 中即可,剩余任选。记
π
(
n
)
\pi(n)
π(n) 为
n
n
n 以内质数个数,则答案为
∑
x
=
?
n
2
?
+
1
n
[
2
c
(
x
)
?
1
]
?
2
π
(
n
)
?
c
(
x
)
\sum_{x=\lfloor{n\over 2}\rfloor+1}^n\big[2^{c(x)}-1\big]\cdot 2^{\pi(n)-c(x)}
x=?2n??+1∑n?[2c(x)?1]?2π(n)?c(x) 常数项
2
π
(
n
)
2^{\pi(n)}
2π(n) 平凡。再提出
?
2
π
(
n
)
-2^{\pi(n)}
?2π(n) 后,仅余
2
?
c
(
x
)
2^{-c(x)}
2?c(x) 。显然它是积性函数,有
f
(
p
k
)
=
1
2
??
(
k
∈
N
+
)
f(p^k)={1\over 2}\;(k\in\N^+)
f(pk)=21?(k∈N+),用
m
i
n
25
\tt min25
min25 筛它就完事儿了!时间复杂度
O
(
n
0.75
ln
?
n
)
\mathcal O({n^{0.75}\over\ln n})
O(lnnn0.75?) 。
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
typedef long long llong;
inline int readint(){
int a = 0, c = getchar(), f = 1;
for(; !isdigit(c); c=getchar())
if(c == '-') f = -f;
for(; isdigit(c); c=getchar())
a = (a<<3)+(a<<1)+(c^48);
return a*f;
}
const int MAXN = 100005;
int primes[MAXN], primes_size;
bool isPrime[MAXN];
void sieve(int n){
memset(isPrime+2,true,n-1); rep(i,2,n){
if(isPrime[i]) primes[++ primes_size] = i;
for(int j=1; j<=primes_size&&primes[j]<=n/i; ++j){
isPrime[i*primes[j]] = false;
if(i%primes[j] == 0) break;
}
}
}
const int MOD = 998244353, inv2 = (MOD+1)>>1;
inline int qkpow(llong b,int q){
llong a = 1;
for(; q; q>>=1,b=b*b%MOD)
if(q&1) a = a*b%MOD;
return int(a);
}
int haxi[2][MAXN];
# define _id(x) ((x) < MAXN ? haxi[0][x] : haxi[1][n/(x)])
llong w[MAXN<<1]; int g[MAXN<<1];
void step_one(llong n){
static int tot; tot = 0;
for(llong i=1; i<=n; i=n/w[tot]+1){
w[++ tot] = n/i, _id(w[tot]) = tot;
g[tot] = int((w[tot]-1)%MOD);
}
for(int j=1; j<=primes_size&&primes[j]<=n/primes[j]; ++j)
for(int i=1; i<=tot&&primes[j]<=w[i]/primes[j]; ++i){
g[i] -= g[_id(w[i]/primes[j])]-j+1;
if(g[i] < 0) g[i] += MOD;
}
}
llong step_two(const llong &n,llong x,int i){
if(primes[i] > x) return 0;
llong sum = llong(g[_id(x)]+MOD-i+1)*inv2%MOD;
for(; i<=primes_size&&primes[i]<=x/primes[i]; ++i)
for(llong t=primes[i],nxt=x/t; t<=nxt; t*=primes[i])
sum = (sum+(1+step_two(n,x/t,i+1))*inv2)%MOD;
return sum;
}
int main(){
llong n; scanf("%lld",&n);
sieve(MAXN-5); step_one(n);
const int coe = qkpow(2,g[1]);
llong ans = (n-step_two(n,n,1)+MOD)%MOD;
step_one(n >>= 1); ans += step_two(n,n,1);
printf("%lld\n",(ans+MOD-n%MOD)*coe%MOD);
return 0;
}
后记
我们永远滴神
R
a
i
n
y
b
u
n
n
y
\sf{Rainybunny}
Rainybunny 自然是轻松发现结论。事实上,所有人都能轻松发现结论;在角落有一句注脚:
O
n
e
I
n
D
a
r
k
\sf OneInDark
OneInDark 除外。
这让我有点想起另一道题:
[
2
,
n
]
[2,n]
[2,n] 每个数字最多用一次,找出尽可能多的数字对
(
a
i
,
b
i
)
(a_i,b_i)
(ai?,bi?) 使得
a
i
,
b
i
a_i,b_i
ai?,bi? 不互质。做法是,对于奇质数
p
p
p,将其倍数全部匹配——若有奇数个,保留
2
p
2p
2p 。那么最后剩下一群偶数,任意匹配。最多剩下一个有用数字(大于
?
n
2
?
\lfloor{n\over 2}\rfloor
?2n?? 的质数是无用的),故为答案下界。题目名已失落。
可是,这有什么用呢?哪怕我听到结论后,能举出一千个例证,我能想到一次吗?我只能尽力做到我的最好;即使我的最好,就是
D
D
(
X
Y
X
)
\sf DD(XYX)
DD(XYX) 的起点,我还是需要、也只能以自己的最好为目标。
我拿了
0
0
0 分。这就是我的最好。
“《离骚》者,犹离忧也。”——司马迁《史记》
以为题易而做兮,做至时乎已尽。
欲摆烂而不交兮,恐校长之榜一。
闻众人之同摆兮,飘飘然其离去。
然雨兔曰“结论易”,方知被骗而欲反兮。
未及落座而世皆
A
K
AK
AK 予独零,小丑竟是我自己!
|