首页 > 其他分享 >P9308 「DTOI-5」#1f1e33 题解

P9308 「DTOI-5」#1f1e33 题解

时间:2024-08-01 20:17:21浏览次数:7  
标签:le P9308 limits 题解 sum mid varphi ij DTOI

声明:截止 \(2024.8.1\),拿下洛谷最优解最短解,代码长度不到 1k。复杂度 \(O(n\log \log n)\)。

先骂:官方题解菜!这种纯洁的数论题居然敢引入 NTT 作为标算,说明出题人不会推式子。

还有题解区一车 \(\log\) 的题解凭啥顶那么上面,推的一坨狗屎推出来的复杂度还不优秀。


说明:下面除法默认下取整,为了方便部分分数用 \(/\) 代替,若无特殊说明 \((i,j)\) 都表示取 \(\gcd\)。

下文记当前求的 \(f(n)\) 为 \(ans\),\(f\) 后面设成了其他函数。

套路性的枚举 \(\gcd\):\(ans=\sum\limits_{d=1}^n\sum\limits_{1\le j,k,j+k\le n/d}[(j,k)=1]\text{lcm}(n-d(j+k),d)\)。

注意到:\(\text{lcm}(n-d(j+k),d)=\dfrac{d(n-d(j+k))}{\gcd(n-d(j+k),d)}=\dfrac{d}{(d,n)}\cdot (n-d(j+k))\)。

\(ans=\sum\limits_{d=1}^n\dfrac{d}{(d,n)}\sum\limits_{1\le j,k,j+k\le n/d}[(j,k)=1](n-d(j+k))\),枚举 \(s=j+k\),枚举 \(j\),则 \((j,k)=(s,j)\):

\(ans=\sum\limits_{d=1}^n\dfrac{d}{(d,n)}\sum\limits_{s=2}^{n/d}(n-ds)\sum\limits_{j=1}^{s-1} [(s,j)=1]=\sum\limits_{d=1}^n\dfrac{d}{(d,n)}\sum\limits_{s=2}^{n/d}(n-ds)\varphi(s)=\sum\limits_{i=1}^n\dfrac{i}{(n,i)}\sum\limits_{ij\le n} [j\ge 2](n-ij)\varphi(j)\)。


枚举 \((i,n)\):

\[\begin{aligned}ans&=\sum\limits_{i=1}^n\dfrac{i}{(n,i)}\sum\limits_{ij\le n} [j\ge 2](n-ij)\varphi(j) \\ &=\sum\limits_{d\mid n}d\sum\limits_{i=1}^{n/d}[(i,n/d)=1]i\sum\limits_{ij\le n/d} [j\ge 2](n/d-ij)\varphi(j) \\ &=\sum\limits_{d\mid n}d\sum\limits_{dD\mid n}\mu(D)D^2 \sum\limits_{i=1}^{n/dD}i\sum\limits_{ij\le n/dD} [j\ge 2](n/dD-ij)\varphi(j) \\ &=\sum\limits_{T\mid n}T\sum\limits_{D\mid T}\mu(D)D\sum\limits_{i=1}^{n/T}i\sum\limits_{ij\le n/T} [j\ge 2](n/T-ij)\varphi(j) \\ &=\sum\limits_{T\mid n}f(T)g(n/T)=(f*g)(n)\end{aligned}\]

其中 \(f(T)=T\sum\limits_{d\mid T}\mu(d)d,g(n)=\sum\limits_{i=1}^{n}i\sum\limits_{ij\le n} [j\ge 2](n-ij)\varphi(j)\)。

此时若计算出 \(f(1\sim n),g(1\sim n)\),注意到显然 \(f\) 是积性函数。

求 \(1\sim n\) 时的 \(ans\) 做个快速狄利克雷卷积即可,狄卷的复杂度是 \(O(n\log\log n)\)。


考虑求 \(f\),记 \(f_0(n)=f(n)/n\),则可以如下线性筛求 \(f_0\):

\(f_0(np)=\begin{cases}1-p(n=1)\\f_0(n)f_0(p)(p\nmid n)\\f_0(n)(p\mid n)\end{cases}\)


扣掉 \([j\ge 2]\),则多算的部分为:\(\sum\limits_{i=1}^n i(n-i)=\dbinom{n+1}{3}\)。

于是 \(g(n)=h(n)-\dbinom{n+1}{3},h(n)=\sum\limits_{ij\le n} i(n-ij)\varphi(j)\)。

\(h(n)=\sum\limits_{s=1}^n(n-s)\sum\limits_{d\mid s}d\varphi(n/d)=\sum\limits_{s=1}^n(n-s)F(s)\),其中 \(F(s)=\sum\limits_{d\mid s}d\varphi(n/d)\)。

可以如下线性筛求 \(F\):

\(F(np)=\begin{cases}2p-1(n=1)\\F(n)F(p)(p\nmid n)\\p(2F(n)-pF(n/p))(p\mid n)\end{cases}\)

然后随便前缀和一下就能求出 \(h\) 了。

于是 \(f,g\) 都可以线性求,最后狄利克雷卷积一下做完。


留几道思考问题:

  • 如何证明 \(f\) 是积性函数?

  • 如何能推出线性筛求 \(f_0,F\) 的式子?

  • 请尝试论证 \(F(1\sim n)\) 的值能在 int 范围内存下,即线性筛的过程中不需要取模。

  • 一种及其巧妙的把 \(F\) 转化为 \(g\) 的方法为:令 \(F_0(n)=F(n)-n\)。
    对 \(F_0\) 做两次前缀和得到 \(F'\),此时 \(F(n)=F'(n-1)\),请证明并尝试正向推出此做法。

$\texttt{code}$
#include<bits/stdc++.h>
#define LL long long
#define fr(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
const int N=1e6+5,mod=998244353;
int n,pr[N/10],f[N],g[N];bool v[N];
inline int md(int x){return x>=mod?x-mod:x;}
inline void init(int M)
{
	f[1]=g[1]=1;
	for(int i=2;i<=M;i++)
	{
		if(!v[i]) pr[++pr[0]]=i,f[i]=1-i,g[i]=2*i-1;
		for(int j=1,p=2;j<=pr[0]&&i*p<=M;p=pr[++j])
		{
			v[i*p]=1;
			if(i%p==0){f[i*p]=f[i];g[i*p]=p*(2*g[i]-p*g[i/p]);break;}
			f[i*p]=f[i]*f[p];g[i*p]=g[i]*g[p];//注意此处不需要取模减小常数
		}
	}//线性筛求 f_0,F
	for(int i=1;i<=M;i++) f[i]=1ll*(f[i]+mod)*i%mod,g[i]=md(g[i]-i+g[i-1]);//f 记得点乘回 i
	for(int i=1;i<=M;i++) g[i]=md(g[i]+g[i-1]);
	for(int i=M;i;i--) g[i]=g[i-1];g[1]=0;//巧妙方法求出 g
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;init(n);
	for(int i=1;i<=pr[0];i++) for(int j=n/pr[i];j;j--) 
		for(LL k=pr[i];j*k<=n;k*=pr[i]) g[j*k]=(g[j*k]+1ll*g[j]*f[k])%mod;
	//按照我给的链接材料做快速狄卷
	for(int i=1;i<=n;i++) cout<<g[i]<<" ";
	return 0;
}

标签:le,P9308,limits,题解,sum,mid,varphi,ij,DTOI
From: https://www.cnblogs.com/HaHeHyt/p/18337338

相关文章

  • 2024牛客暑期多校训练营6 A.cake(题解)
    A.Cake题意两个人玩游戏,游戏分两阶段第一阶段在一棵有根树上轮流走,走到叶子停止,有根树边上有01标记,记录下走过的01串第二阶段分蛋糕,Oscar按自己的意愿切蛋糕,然后按照第一阶段获得的01串顺序依次拿蛋糕(1代表Grammy拿,0代表Oscar拿)两人都想让自己获得尽量多的蛋糕,......
  • CF1997F Chips on a Line 题解
    注意到操作是可逆的,可以先把所有筹码移动到位置\(1\),再进行若干次操作使筹码数量最小化。那么我们只需要对每一个\(i\)知道有多少种情况把筹码全移动到位置\(1\)后恰好有\(i\)个筹码,和这类情况的最少筹码数。记\(f_i\)表示斐波那契数列的第\(i\)项,显然一个位置\(i\)......
  • Luogu P1613 跑路 题解 [ 蓝 ] [ 倍增 ] [ Floyd 最短路 ] [ 状压 dp ]
    跑路:绝佳倍增好题,思路是化\(2^k\)为\(1\),倍增起预处理作用。最近不知道是撞了什么运,前一脚看的是绿题,写完之后交一发,发现直接被lxl升蓝了,血赚。思路:Floyd首先观察到每次走\(2^k\)的代价为\(1\),我们可以预处理出每次走\(2^i\)能到哪些点。但为了让这题的代码更好实......
  • 题解:CF1015D Walking Between Houses
    题解:CF1015DWalkingBetweenHouses算法模拟,分类讨论分析首先,设每步走的距离为\(t_i\),我们发现\(t_i\)应是满足\(1\let_i\len-1\)的。那么就很容易推出NO的情况:当\(s<k\)时,由于每一步都要至少走一个单位,所以\(k\)次步数肯定用不完,而题目要求恰好\(k\)次;当......
  • CF716B Complete the Word 题解
    CF716BCompletetheWord题解分析首先观察数据范围是\(50000\),可以考虑\(O(n)\)暴力。在字符串中枚举子串开始的位置\(i\),然后再枚举\(i\)到\(i+25\),开个桶统计每个大写字母出现的次数,如果大于\(1\)就直接break。统计完之后剩下的就都是问号了,可以随便填,所以这个子......
  • P3043 [USACO12JAN] Bovine Alliance G 题解
    P3043[USACO12JAN]BovineAllianceG题目传送门思路首先分情况讨论每种联通块的可能,有三种不同的情况会对答案\(ans\)产生不同的贡献。联通块有环如图,因为每条边都有要有归属,所以环上的边只能全都顺时针或逆时针属于某个点,且不在环上的点仅有一种可能。因此该情况对答......
  • 题解:CF687C The Values You Can Make
    CF687CTheValuesYouCanMake题解题目翻译感觉不明不白的(至少我看了几遍没看懂),这里给个较为清晰的题面。题目描述给你\(n\)个硬币,第\(i\)个硬币有一个价值\(c_i\),你需要从中选出一些价值和为\(k\)的硬币组成一个集合,再输出这个集合中硬币可能组成的价值和。算法动......
  • 题解:CF559B Equivalent Strings
    CF559BEquivalentStrings题解题目描述吐槽一下,题目翻译有歧义。思路分析你会发现,当你需要判断字符串\(a,b\)是否等价时,如果长度为偶数,需要继续判断字符串\(a\)拆分的字串。所用知识s.substr(i,j)//在字符串s中,从位置i开始截取长度为j的字串参考代码#include<bits......
  • 题解:CF718A Efim and Strange Grade
    CF718AEfimandStrangeGrade题解算法贪心+模拟思路分析显然,要最优每一次进位就只能五入不能四舍。而且当我们五入时,要取位数最高的。比如说\(1.3535\),我们有两种进位方式,一种是进位成\(1.4\),一种是进位成\(1.354\),显然前者更优。那这道题给的次数有啥用呢?考虑一种“......
  • P10511 方差 题解
    【题目简述】定义一个长度为\(n\)的序列\(a\)的方差为:\(s^2=\frac{1}{n}\sum_{i=1}^n(a_i-\overline{a})^2\)。\(\sum\)为累加求和符号,\(\overline{a}\)为序列\(a\)的平均数。给定\(m\)个形如\([l,r,b]\)的组合,表示\(a_l,a_{l+1},\ldots,a_r\)为\(b\)。给定......