[硫化铂]卿且去
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[硫化铂]卿且去相关的知识,希望对你有一定的参考价值。
卿且去
题解
首先有结论,在
(
⌊
n
2
⌋
,
n
]
(\\lfloor \\fracn2\\rfloor,n]
(⌊2n⌋,n]中的所有数都被选择肯定是一组最优解。
我们可以考虑把原先的数分成
[
1
,
⌊
n
2
⌋
]
[1,\\lfloor\\fracn2\\rfloor]
[1,⌊2n⌋]与
(
⌊
n
2
⌋
,
n
]
(\\lfloor\\fracn2\\rfloor,n]
(⌊2n⌋,n]两部分,如果将倍数关系看成连边的话,可以发现,在第二部分的子图中不存在任何边,且第一部分中任何一个点都向着后部分至少一个点连边。
在这种情况下,我们的选择数相当于从图中选出一个独立集。
显然,对于不存在任何边的第二部分,肯定是一组合法解,我们现在要说明为什么它是最优解。
如果我们在第一部分中选择了集合
S
=
a
1
,
a
2
,
.
.
.
,
a
m
S=\\a_1,a_2,...,a_m\\
S=a1,a2,...,am,那么第二部分中至少有一个等大的集合不能选择。
因为
∀
x
∈
[
1
,
⌊
n
2
⌋
]
,
∃
k
∈
N
+
,
x
×
2
k
∈
(
⌊
n
2
⌋
,
n
]
\\forall x\\in [1,\\lfloor\\fracn2\\rfloor],\\exists k\\in N^+,x\\times 2^k\\in (\\lfloor\\fracn2\\rfloor ,n]
∀x∈[1,⌊2n⌋],∃k∈N+,x×2k∈(⌊2n⌋,n],所以集合中每个
a
i
a_i
ai肯定在第二部分中有一个点
b
i
=
2
k
×
a
i
b_i=2^k\\times a_i
bi=2k×ai。
由于
S
S
S中的任意两个数都不呈倍数关系,所以这些
b
i
b_i
bi都两两不同,也就是说我们在第二部分中至少有一个大小为
m
m
m的集合不能选择。
所以,我们在第一部分中一个都不选,第二部分全选,肯定是一组最优解。
考虑如何通过上面的结论计算答案,我们可以尝试计算当每个质数出现在集合中会使得多少个在
(
⌊
n
2
⌋
,
n
]
(\\lfloor\\fracn2\\rfloor,n]
(⌊2n⌋,n]中的数可以被选择。
由于不同的两个质数可以使得同一个数被选择,所以显然需要容斥,记
P
P
P为质数集,
π
(
i
)
\\pi(i)
π(i)表示
i
i
i的不同质因子个数。
A
n
s
=
∑
i
=
1
n
−
μ
(
i
)
(
⌊
n
i
⌋
−
⌊
n
2
i
⌋
)
2
∣
P
∣
−
π
(
i
)
=
−
2
∣
P
∣
∑
(
⌊
n
i
⌋
−
⌊
n
2
i
⌋
)
μ
(
i
)
2
−
π
(
i
)
Ans=\\sum_i=1^n-\\mu(i)(\\lfloor\\fracni\\rfloor-\\lfloor\\fracn2i\\rfloor)2^|P|-\\pi(i)=-2^|P|\\sum_(\\lfloor\\fracni\\rfloor-\\lfloor\\fracn2i\\rfloor)\\mu(i) 2^-\\pi(i)
Ans=i=1∑n−μ(i)(⌊in⌋−⌊2in⌋)2∣P∣−π(i)=−2∣P∣∑(⌊in⌋−⌊2in⌋)μ(i)2−π(i)对于上式,我们发现
(
⌊
n
i
⌋
−
⌊
n
2
i
⌋
)
(\\lfloor\\fracni\\rfloor-\\lfloor\\fracn2i\\rfloor)
(⌊in⌋−⌊2in⌋)是可以整除分块的,而
f
(
i
)
=
μ
(
i
)
2
−
π
(
i
)
f(i)=\\mu(i)2^-\\pi(i)
f(i)=μ(i)2−π(i)又是一个积性函数。
于是我们很容易想到通过
m
i
n
25
min25
min25等方法去计算每个块里的
f
(
i
)
f(i)
f(i)之和。
由于像
m
i
n
25
min25
min25筛这种,他会将每个
∑
i
=
1
⌊
n
d
⌋
f
(
i
)
\\sum_i=1^\\lfloor\\fracnd\\rfloorf(i)
∑i=1⌊dn⌋f(i)的值都算出来,恰好契合我们的整除分块,我们可以在
O
(
n
3
4
ln
n
)
O\\left(\\fracn^\\frac34\\ln n\\right)
O(lnnn43)的时间中将它们都算出,所以是可以采取这种方法通过的。
时间复杂度
O
(
n
3
4
ln
n
)
O\\left(\\fracn^\\frac34\\ln n\\right)
O(lnnn43)。
建议采用递推的
m
i
n
25
min25
min25筛,由于需要算多点,递归版的需要记忆化,不太好搞,常数也大。
不过 偶耶 好像也有不用多点求值,只用算单点的方法。
源码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define MAXN 400005
#define MAXM 50000005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL;
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int mod=1e5+3;
const int inv2=499122177;
const int fiv2=499122176;
const int jzm=2333;
const int zero=2000;
const int M=100000;
const int orG=3,ivG=332748118;
const long double Pi=acos(-1.0);
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x)return x<0?-x:x;
template<typename _T>
void read(_T &x)
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0')if(s=='-')f[硫化铂]传染