[硫化铂]卿且去

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],kN+,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=1nμ(i)(in2in)2Pπ(i)=2P(in2in)μ(i)2π(i)对于上式,我们发现 ( ⌊ n i ⌋ − ⌊ n 2 i ⌋ ) (\\lfloor\\fracni\\rfloor-\\lfloor\\fracn2i\\rfloor) (in2in)是可以整除分块的,而 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=1dnf(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[硫化铂]传染

[硫化铂]密码

[硫化铂]treecnt

[硫化铂]启程的日子

[硫化铂]好

[硫化铂]未来