首页 > 其他分享 >高维前缀和

高维前缀和

时间:2023-12-07 16:37:11浏览次数:27  
标签:前缀 times seed 数组 维度 高维

对于求高维前缀和,我的理解是在维度数乘总点数的复杂度下求前缀和。
首先可以先看看二维前缀和。
如果使用容斥的方法,像这样:

for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		f[i][j]=a[i][j]+f[i-1][j]+f[i][j-1]-f[i-1][j-1];
	}
}

那么就是\(2^w\times n\times m\)。(\(w\)是维度)
假设说我们考虑先枚举维度。
在第一维,定义\(g_{i,j}=\sum_{k=1}^i a_{k,j}\)。
在第二维,定义\(f_{i,j}=\sum_{k=1}^j g_{i,k}\)。
则\(f\)数组就是\(a\)数组的二维前缀和数组。
照这个方法推广到\(w\)维就可以了。
但是高维要如何开数组?我的理解是用一种类似于哈希的方式,例如下面这道题:
洛谷P5495
给定长度为\(n\)的\(a\)数组,求长度为\(n\)的\(b\)数组。\(b_j=\sum_{i\mid j} a_i\)
这里我们把质数作为维度,例如$2,0,1,0,\dots $就是\(2\)这一维是\(2\),\(5\)这一维是\(1\),其他维都是\(0\)的状态,直接哈希成\(2^2\times 3^0\times 5^1\times \dots =20\),有效状态一共\(n\)个,用高维前缀和直接解决。
代码

#include<iostream>
#define uint unsigned int
using namespace std;
uint seed;
inline uint getnext(){
	seed^=seed<<13;
	seed^=seed>>17;
	seed^=seed<<5;
	return seed;
}
int n;
bool prime[20000010];
int ss[2000010];
uint a[20000010];
void oula(){
	for(int i=2;i<=n;i++){
		if(prime[i]==0){
			ss[++ss[0]]=i;
		}
		for(int j=1;j<=ss[0]&&ss[j]*i<=n;j++){
			prime[i*ss[j]]=1;
			if(i%ss[j]==0){
				break;
			}
		}
	}
}
int main(){
	cin>>n>>seed;
	oula();
	for(int i=1;i<=n;i++){
		a[i]=getnext();
	}
	for(int i=1;i<=ss[0];i++){
		for(int j=1;j*ss[i]<=n;j++){
			a[j*ss[i]]+=a[j];
		}
	}
	uint ans=0;
	for(int i=1;i<=n;i++){
		ans=ans^a[i];
	}
	cout<<ans;
	return 0;
}

标签:前缀,times,seed,数组,维度,高维
From: https://www.cnblogs.com/z-2-we/p/17882320.html

相关文章

  • 刷题 字典树 LCP(最长公共前缀)
    2023.12.5cf1902E字典树的功能根据字典树的概念,我们可以发现:字典树的本质是把很多字符串拆成单个字符的形式,以树的方式存储起来。所以我们说字典树维护的是”字典“。那么根据这个最基本的性质,我们可以由此延伸出字典树的很多妙用。简单总结起来大体如下:1、维护字符串集合(即......
  • 2023年广东工业大学腾讯杯新生程序设计竞赛不知道叫什么名字(前缀和)
    需要的是男生女生数量相同,做个转化,女生变成-1,然后求一遍前缀和,我们希望找到最长的满足\(sum(l,r)=0\)的区间也就是\(sum(r)-s(l-1)=0\)考虑枚举右端点,找到最左端和它相等的sum就是对于当前右端点的最长的。最开始想了个二分答案的假做法,011100,这里答案是6,长度为4不满足......
  • 前缀和/差分——acwing算法基础课笔记
    个人笔记,欢迎补充,指正。一维前缀和对于数组:a[1],a[2],a[3]...a[n];其前缀和数组为s[i]=a[1]+a[2]+...+a[i];下标必须从1开始求前缀和1for(inti=1;i<n;++i)2s[i]=s[i-1]+a[i];s[0]需要定义为0作用求原数组里一段数(l,r)的和......
  • CCF认证——202109-2 贡献的变化——差分维护,前缀和算答案
    https://www.acwing.com/problem/content/4010/http://118.190.20.162/view.page?gpid=T130脑子一热抱着玩的心态试了一下三分,当然炸了,就当初认识三分了。正解是考虑p的变化的影响,p变成p+1的时候,答案的值取决于p属于相邻递增数对的值域区间的数量。也可以考虑递减的情况,两......
  • 前缀和和后缀和
    1.Problem-1791D-Codeforces定义函数 f⁡()f() 表示字符串 x 中不同字符的数量。现给定一个字符串 S,将它分割为两个字符串 a,b。求出:max⁡(f⁡()+f⁡())max(f(a)+f(b))。我们可以搞一个前缀和 a 和一个后缀和 b,分别表示 f⁡(S1​∼Si​) 和 f(Si​∼Sn​)。然......
  • 前缀和算法总结
    前缀和思维导图:一维前缀和算法模版:1#include<iostream>23usingnamespacestd;45constintN=100010;67intn,m;8ints[N];910intmain()11{12scanf("%d%d",&n,&m);13for(inti=1;i<=n;i++)14......
  • (字符串)02-最长公共前缀
    1importjava.util.*;23publicclassSolution{4/**5*@paramstrsstring字符串一维数组6*@returnstring字符串7*/8publicStringlongestCommonPrefix(String[]strs){9//判空数组10if(strs.lengt......
  • 前缀和、差分
    前缀和、差分前缀和可以快速求区间和。差分相当于前缀和的逆运算。前缀和、差分都是以空间换时间的算法前缀和定义前缀和可以简单理解为「数列的前n项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度。一维前缀和题目一LuoguP8218【深进1.例1】求区间和#in......
  • 差分与前缀和学习笔记
    本来是不想写这篇博客的,但为了课前十分钟还是来水一发前缀和简介继续引用OI-Wiki的话(OI-Wiki$yyds$!):前缀和可以简单理解为「数列的前$n$项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度。也就是说,我们能使用$O(n)$的时间进行预处理,在$O(1)$的时间内求出......
  • acwing 第 130 场周赛  (前缀和,dfs,对不同边的处理)
      #include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<climits>usingnamespacestd;typedeflonglongLL;constintN=5010;intn;inta[N];LLs[N];LLget(intl,intr){return......