ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LG模拟赛#1 T2 肯德基,powerful number,寻找构造函数的规律

2021-02-23 10:03:05  阅读:260  来源: 互联网

标签:LG 前缀 int sum powerful long sqrt pk 构造函数


正题

求 n n n 以内所有正整数的最大平方因子的和。答案对 2 64 2^{64} 264取模。

tips: x x x 是 y y y 的平方因子,当且仅当 x x x 是 y y y 的因子且 x \sqrt x x ​恰为整数。

显然设 F ( x ) F(x) F(x)为x的最大平方因子。
容易发现 F ( x ) F(x) F(x)是一个积性函数,且 F ( p k ) = p k − ( k m o d    2 ) F(p^k)=p^{k-(k\mod 2)} F(pk)=pk−(kmod2)
既然是求一个积性函数的前缀和,自然就想到了使用杜教筛或者 m i n _ 25 min\_{25} min_25筛来求解,很遗憾不能通过此题。
还有一种新方法是powerful number,它能在快速计算构造函数G的前缀和的情况下,用 O ( n ) O(\sqrt n) O(n ​)的时间算出前缀和。可以先参考我这一篇Blog
这题则可以构造 G ( x ) = 1 , H ∗ G = F G(x)=1,H*G=F G(x)=1,H∗G=F
则答案为 ∑ i = 1 n H ( i ) ( n / i ) \sum_{i=1}^n H(i)(n/i) ∑i=1n​H(i)(n/i)
如果我们暴力枚举出每一个powerful number并进行求解,那么时间复杂度是 O ( T n ) O(T\sqrt n) O(Tn ​)的,依然不能通过此题。
我们尝试找规律?
由于 H = F / G H=F/G H=F/G,且这个G是一个常值函数1,所以H是一个积性函数且在质数的指数幂上是F的差分
为什么这么说,举个例子 F ( p k ) = ∑ i = 0 k G ( p i ) H ( p k − i ) = ∑ i = 0 k H ( p i ) F(p^k)=\sum_{i=0}^k G(p^i)H(p^{k-i})=\sum_{i=0}^k H(p^i) F(pk)=∑i=0k​G(pi)H(pk−i)=∑i=0k​H(pi),所以 F F F在质数的指数幂上是 H H H的前缀和,而 H H H则是 F F F的差分。
所以可以轻松得到 H ( p 2 k ) = p 2 k − 2 ( p 2 − 1 ) , H ( p 2 k + 1 ) = 0 H(p^{2k})=p^{2k-2}(p^2-1),H(p^{2k+1})=0 H(p2k)=p2k−2(p2−1),H(p2k+1)=0
哦!
所以 H H H只有在完全平方数有值,那么式子就更简单了:
∑ i = 1 n H ( i 2 ) ⌊ n i 2 ⌋ \sum_{i=1}^{\sqrt n}H(i^2)\lfloor \frac{n}{i^2}\rfloor ∑i=1n ​​H(i2)⌊i2n​⌋
用平凡的整除分块写一写,发现时间复杂度好像不对,却发现过了?
原因就在于后面的这个分块对象,可以帮助我们将时间复杂度降到 O ( n 1 / 3 ) O(n^{1/3}) O(n1/3)。
分类讨论一下就可:
当 i 2 < = n 2 / 3 i^2<=n^{2/3} i2<=n2/3时, i < = n 1 / 3 i<=n^{1/3} i<=n1/3,这部分只需要 O ( n 1 / 3 ) O(n^{1/3}) O(n1/3)就可以完成。
当 i 2 > n 2 / 3 时 i^2>n^{2/3}时 i2>n2/3时, ⌊ n i 2 ⌋ < = n 1 / 3 \lfloor \frac n {i^2}\rfloor<=n^{1/3} ⌊i2n​⌋<=n1/3,这部分也只需要 O ( n 1 / 3 ) O(n^{1/3}) O(n1/3)就可以完成,另外,听说求sqrt时间复杂度为 O ( 1 ) O(1) O(1)

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
const int N=10000010;
int T,p[N];
long long n;
bool vis[N];
ull h[N];

int main(){
	scanf("%d",&T);
	n=10000000;h[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) p[++p[0]]=i,h[i]=1ll*i*i-1;
		for(int j=1;j<=p[0] && i*p[j]<=n;j++){
			vis[i*p[j]]=true;
			if(i%p[j]==0) {h[i*p[j]]=h[i]*p[j]*p[j];break;}
			h[i*p[j]]=h[i]*h[p[j]];
		}
	}
	for(int i=2;i<=n;i++) h[i]+=h[i-1];
	while(T--){
		scanf("%lld",&n);
		int l=1,r=0;
		ull ans=0;
		while(1ll*l*l<=n){
			r=sqrtl(n/(n/l/l));
			ans+=(h[r]-h[l-1])*(n/l/l);
			l=r+1;
		}
		printf("%llu\n",ans);
	}
}

标签:LG,前缀,int,sum,powerful,long,sqrt,pk,构造函数
来源: https://blog.csdn.net/Deep_Kevin/article/details/113972000

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有