c++算法之前缀和

目录

前缀和原理和特点

实现前缀和

例题

蓝桥oj3382 区间次方和

问题描述

输入格式

输出格式

样例输入

样例输出

蓝桥oj3419小郑的蓝桥平衡串

问题描述

输入格式

输出格式

样例输入

样例输出


前缀和原理和特点

prefix表示前缀和,前缀和由一个用户输入的数组生成。

prefix[x] = a[1]+a[2]+...a[i]

同理:prefix[x] = prefix[x-1]+a[x]

求一段区间的和:sum(l,r) = prefix[r]-prefix[l-1]

但是注意:prefix是一种预处理算法,只适用于a数组为静态数组的情况,即a数组中的元素在区间和查询过程中不会进行修改。

如果需要实现“先区间修改,再区间查询”可以使用差分数组,如果需要“一边修改一边查询”需要使用树状数组或线段树等数据结构。

实现前缀和

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

例题

蓝桥oj3382 区间次方和

问题描述

给定一个长度为 nn 的整数数组 aa 以及 mm 个查询。

每个查询包含三个整数 l,r,kl,r,k 表示询问 l∼rl∼r 之间所有元素的 kk 次方和。

请对每个查询输出一个答案,答案对 109+7109+7 取模。

输入格式

第一行输入两个整数 n,mn,m 其含义如上所述。

第二行输入 nn 个整数 a[1],a[2],...,a[n]a[1],a[2],...,a[n]。

接下来 mm 行,每行输入三个整数 l,r,kl,r,k 表示一个查询。

输出格式

输出 mm 行,每行一个整数,表示查询的答案对 109+7109+7 取模的结果。

样例输入

5 3
1 2 3 4 5
1 3 2
2 4 3
3 5 1

样例输出

14
99
12

#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5 + 9;
using ll = long long;
const ll p = 1e9 + 7;
ll a[6][N], prefix[6][N];


int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n, m; cin >> n >> m;
	for (int i = 1; i <= n; i++)cin >> a[1][i];

	for (int i = 2; i <= 5; ++i)
		for (int j = 1; j <= n; ++j)
			a[i][j] = a[i - 1][j] * a[1][j];

	for (int i = 1; i <= 5; ++i)
	{
		for (int j = 1; j <= n; j++)
			prefix[i][j] = (prefix[i][j - 1] + a[i][j]);
	}
		while (m--)
		{
			int l, r, k; cin >> l >> r >> k;
			cout << (prefix[k][r] - prefix[k][l-1]) % p << endl;
		}

	
	// 请在此输入您的代码
	return 0;
}

蓝桥oj3419小郑的蓝桥平衡串

问题描述

平衡串指的是一个字符串,其中包含两种不同字符,并且这两种字符的数量相等。

例如,ababab 和 aababb 都是平衡串,因为每种字符各有三个,而 abaab和 aaaab 都不是平衡串,因为它们的字符数量不相等。

平衡串在密码学和计算机科学中具有重要应用,比如可以用于构造哈希函数或者解决一些数学问题。

小郑拿到一个只包含 L、Q 的字符串,他的任务就是找到最长平衡串,且满足平衡串的要求,即保证子串中 L、Q 的数量相等。

输入格式

输入一行字符串,保证字符串中只包含字符 L、Q。

输出格式

输出一个整数,为输入字符串中最长平衡串的长度。

样例输入

LQLL

样例输出

2

#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
char s[N];

int prefix[N];

int main()
{
	cin >> s + 1;
	int n = strlen(s + 1);
	for (int i = 1; i <= n; ++i)prefix[i] = prefix[i - 1] + (s[i] == 'L' ? 1 : -1);

	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		for (int j = i; j <= n; j++)
		{
			if (prefix[j] - prefix[i - 1] == 0)ans = max(ans, j - i + 1);
		}
	}
	cout << ans << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

至尊宝加油

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值