【狄利克雷前缀和 / 后缀和】算法学习

1. 狄利克雷前缀和

问题描述

有数列 {a},求数列 {b} 满足

bk=i|kai

数列长度 n2×107

分析

考虑质因数分解,某个数 x=piαi, 将其写成行向量 (α1,α2,,αk)。 那么每次乘一个素数 pi,使得 αi+1。 于是可以用这个向量描述贡献 xxpi 。这本质上是个 k 维前缀和的过程。

可是素数是无限多的,我们考虑状态压缩,发现只需要用原来的数表示这个向量即可。状态数 O(n)

时间复杂度与埃筛法类似,np=O(nloglogn)

P5495
void init(int N) {
	for(int i=2;i<=N;++i) {
		if(!f[i]) f[i] = 1,p[++p[0]] = i;
		for(int j=1;j<=p[0] && i*p[j]<=N;++j) {
			f[i*p[j]] = 1;
			if(i % p[j] == 0)break;
		}
	}
}
signed main(){
	int n = read(); cin>>seed;
	for(int i=1;i<=n;++i) a[i] = getnext();
	init(n);
	for(int i=1;i<=p[0];++i) {
		for(int j=1; j*p[i] <= n;++j) {
			a[j * p[i]] += a[j];
		}
	}
	uint ans = 0;
	for(int i=1;i<=n;++i) ans ^= a[i];
	cout << ans << endl;
	return 0;
}

posted @   Lates  阅读(190)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示