首页 > 编程语言 >前缀和算法

前缀和算法

时间:2024-02-25 20:02:43浏览次数:17  
标签:cnt ch 前缀 sum 算法 区间 余数

一、简析前缀和

有一系列元素 \(A[a_0,~a_1,~...,~a_n,~...]\),前缀和 \(pre\_sum[n]=A[0]+A[1]+···+A[n]\)。
利用前缀和,我们可以很高效地得到 \([L,~R]\) 的区间和 \(\sum_{i=L}^{R}A[i]=pre\_sum[R]-pre\_sum[L-1]\)。


二、相关问题

2.1 题目简述

P8649 [蓝桥杯 2017 省 B] k 倍区间

2.2 算法简析

设 \(p[n] = A[0]+A[1]+···+A[n]\),则 [L, R] 的区间和为 \(p[R]-p[L-1]\)。题目要求区间和为 \(K\) 的倍数,则 \((p[R]-p[L-1])~|~K\),即 \((p[R]-p[L-1])\equiv 0~(\text{mod}~K)\)。由模运算率,\(p[R]\equiv p[L-1]~(\text{mod}~K)\)。满足该条件,就是满足"K倍区间"。
我们可以统计,在模 \(K\) 的条件下,前缀和同余的个数。例,\(cnt[j]\) 表示前缀和模 \(K\) 的余数为 \(j\) 的个数,则满足"K倍区间"的个数为 \(C_{cnt[j]}^2\)。
需要注意的是,余数为 \(0\) 是一个特殊情况。因为题目允许区间只有一个元素,所以单独一个元素也是满足要求的(说明该元素是 \(K\) 的倍数)。假设余数为 \(0\) 的个数为 \(x\),则满足题目要求的个数为

\[\begin{split} C_x^2+x&=\frac{x(x-1)}{2}+x \\ &=\frac{(x+1)x}{2} \\ &=C_{x+1}^2 \end{split} \]

所以统计余数为 \(0\) 的情况时,要初始化为 \(1\)。

2.3 本题代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAX = 1e5 + 5;

ll N, K, A[MAX], cnt[MAX];

int quickin(void)
{
	int ret = 0;
	bool flag = false;
	char ch = getchar();
	while (ch < '0' || ch > '9')
	{
		if (ch == '-')    flag = true;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9' && ch != EOF)
	{
		ret = ret * 10 + ch - '0';
		ch = getchar();
	}
	if (flag)    ret = -ret;
	return ret;
}

int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	N = quickin(), K = quickin();
	int tmp = 0;
	cnt[0] = 1;
	for (int i = 0; i < N; i++)
	{
		A[i] = quickin();
		tmp = (tmp + A[i]) % K;
		cnt[tmp]++;
	}
	
	ll ans = 0;
	for (int i = 0; i < K; i++)
	{
		if (cnt[i] > 0)
			ans += cnt[i] * (cnt[i] - 1) / 2;
	}
	
	cout << ans << endl;
	
	return 0;	
} 

标签:cnt,ch,前缀,sum,算法,区间,余数
From: https://www.cnblogs.com/hoyd/p/18032840

相关文章

  • 【机器学习算法】KNN鸢尾花种类预测案例和特征预处理。全md文档笔记(已分享,附代码)
    本系列文章md笔记(已分享)主要讨论机器学习算法相关知识。机器学习算法文章笔记以算法、案例为驱动的学习,伴随浅显易懂的数学知识,让大家掌握机器学习常见算法原理,应用Scikit-learn实现机器学习算法的应用,结合场景解决实际问题。包括K-近邻算法,线性回归,逻辑回归,决策树算法,集成学习,聚......
  • SPFA算法
    一、单源最短路径typedeflonglongll;constintMAX=2e3+5;constllINF=numeric_limits<ll>::max();typedefstruct{ intto,worth;}edge;intn,m;vector<edge>G[MAX];lld[MAX];boolvis[MAX];voidspfa(ints){ fill(d+1,d+1+n,......
  • 2024牛客寒假算法基础集训营6
    A.欧拉筛处理出素数直接3重暴力循环找#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;#defineinf0x3f3f3f3fboolis_prime[N];//是否是质数,0为是,1为不是intprime[N];//质数数组inttop=1;//质数的下标intmin_p[N];//最小......
  • 2024牛客寒假算法基础集训营6 H 纷乱的红线 题解
    Question2024牛客寒假算法基础集训营6H纷乱的红线小红拿到了一个圆,以及平面上有\(n\)个点(保证没有三点共线)。现在小红将随机取\(3\)个点画一个三角形,她想知道这个三角形和圆的交点数量的期望是多少?Solution考虑到\(n\le1000\)可以枚举每一条线,计算这一条线和圆的交......
  • 提高组算法-树状数组
    树状数组是当序列动态变化时,依然可以高效率的查询和维护前缀和(或区间和)的数据结构。实现思路现在有\(16\)个数字:\(a[]={1,8,5,9,6,3,9,8,7,2,3,9,6,4,1,7}\)。我们要实现\(2\)个函数:修改其中某个元素的数值。求出前\(n\)个数字的和。但是,这\(2\)个函数要在极......
  • 加密算法/常见编码
    MD51.MD5算法是单向散列算法的一种。单向散列算法也称为HASH算法,是一种将任意长度的信息压缩至某一固定长度(称之为消息摘要)的函数(该压缩过程不可逆)。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息(32位的数字字母混合码)。MD5值是32位或者16位由数字"0-9"和字......
  • 2024牛客寒假算法基础集训营6 G 人生的起落 题解
    Question2024牛客寒假算法基础集训营6G人生的起落定义一个三元组\((x,y,z)\)是“v-三元组”当且仅当该三元组满足以下条件:\(x=z\)\(x>y\)现在需要你构造一个\(n\)个正整数组成的数组,所有元素之和恰好等于\(S\),且恰好有\(k\)个长度威\(3\)的连续子数组......
  • 算法面经
    数组88. 合并两个有序数组经典逆向双指针voidmerge(vector<int>&nums1,intm,vector<int>&nums2,intn){for(inti=m-1,j=n-1,k=m+n-1;~j;k--){nums1[k]=i>=0&&nums1[i]>nums2[j]?nums1[i--]:......
  • 走进Kaggle的未知领域:性别和年龄推断算法解析
    ​1、环境设置:此环节将加载实现笔记本无缝功能的基本模块,包括NumPy、Pandas和TensorFlow等库。此外,它还建立了关键的环境常数,如图像尺寸和学习率,这对后续分析和模型训练至关重要。#Generalimportosimportkerasimportnumpyasnpimportpandasaspdimporttensorflow......
  • Big-Yellow的算法工程师进阶之路
    Big-Yellow的算法工程师进阶之路一、基础算法二、基础数据结构2.1链表三、......