目次
2. 配列が与えられた場合、そのプレフィックスと配列を見つけます
I.はじめに
1. プレフィックスサムとは何ですか?
プレフィックス合計は、クエリの時間の複雑さを軽減するために使用される一種の前処理です。これは数学における最初の n 項の合計のようなものです。
n 個の整数が与えられた場合、m 個のクエリを実行すると、各クエリは間隔内の値の合計を見つけます。
乱暴な方法で記述した場合、各クエリは間隔の左端から右端までループして合計する必要があり、大きな時間計算量が発生します。
この場合、配列の 1 次元のプレフィックスの合計を事前に計算することができます。
たとえば、配列が [1, 1, 1, 1, 1] の場合、プレフィックス合計配列は [1, 2, 3, 4, 5] になります。
2. 違いは何ですか?
違いは、プレフィックスと配列の元の配列に似ています。
たとえば、プレフィックス合計配列が [1, 2, 3, 4, 5] の場合、差分配列は [1, 1, 1, 1, 1] になります。
要約すると、プレフィックスの合計と差は相互演算です。
3. 利点
配列のすべての部分範囲に数値 c を追加し、変更された範囲を合計するように求められた場合。
1. シンプルなアプローチ:
- 間隔を求めて各数値を加算します c
- 一周してからまとめる
加算する間隔や加算する合計が多い場合、時間が長くなりすぎます。
2. 差動アレイを使用する
- 追加する間隔の左端点を見つけて、左端点のみに c を追加します (左端の右側)エンドポイント、そのプレフィックスと配列の両方が c) で追加されます。
- しかし、追加したい加数の範囲は特定の範囲内のみです。この場合、その右端点 +1に対して -c 操作を実行します。 a>、それだけです
2. コードの実装
注: 配列は 1 から開始して保存する必要があります。そうでない場合は、プレフィックスと配列を検索するときに特別な判断が行われます。
1. 配列を与えてその差分配列を見つける
#include<iostream>
using namespace std;
const int N = 1e5 + 5;
int a[N];//原数组
int b[N];//差分数组
int n;//数的个数
//可以将求一个差分数组,分成求1个元素的差分数组
void insert (int c,int i)
{
b[i] += c;
b[i + 1] -= c;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) insert(a[i], i);
for (int i = 1; i <= n; i++) cout << b[i] << " ";
return 0;
}
2. 配列が与えられた場合、そのプレフィックスと配列を見つけます
#include<iostream>
using namespace std;
const int N = 1e5 + 5;
int n;//数的个数
int a[N];//原数组
int s[N];//前缀和数组
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + a[i];//每一个前缀和数组元素一定是它前一个前缀和数组元素加上自己的元素
}
for (int i = 1; i <= n; i++) {
cout << s[i] << " ";
}
return 0;
}
ご協力ありがとうございました!