C++でのサブアレイの最小値の合計
整数Aの配列があるとします。min(B)の合計を見つける必要があります。ここで、BはAのすべての(連続した)サブ配列にまたがっています。大きい場合は、モジュロ10 ^ 9 + 7で答えを返します。したがって、入力が[3,1,2,4]の場合、サブ配列は[3]、[1]、[であるため、出力は17になります。 2]、[4]、[3,1]、[1,2]、[2,4]、[3,1,2]、[1,2,4]、[3,1,2,4] 、したがって、最小値は[3,1,2,4,1,1,2,1,1,1]であり、合計は17です。
これを解決するには、次の手順に従います-
-
m:=1 x 10 ^ 9 + 7
-
2つのメソッドを定義します。add()はa、bを取り、(a mod m + b mod m)mod mを返し、mul()はa、bを取り、(a mod m * b mod m)modm<を返します。 / P>
-
mainメソッドは、配列Aを取得し、スタックstを定義し、n:=配列Aのサイズを設定します
-
サイズnの左側に2つの配列を定義し、-1で埋め、もう1つはサイズnの右側にあり、nで埋めます
-
ans:=0
を設定します -
0からn–1の範囲のiの場合
-
stが空ではなく、A [stack top]> =A [i]の場合、stから削除します
-
stが空でない場合は、left [i]:=top of st
を設定します。 -
iをstに挿入
-
-
stが空でない場合は、stを削除します
-
n –1から0までの範囲のiの場合
-
stが空ではなく、A [stack top]> =A [i]の場合、stから削除します
-
stが空でない場合は、right [i]:=top of st
を設定します。 -
iをstに挿入
-
-
0からn–1の範囲のiの場合
-
leftBound:=i – left [i] + 1、rightBound:=right [i] – 1 – i
-
contri:=1 + leftBound + rightBound +(leftBound * rightBound)
-
ans:=add(ans and mul(contri、A [i]))
-
-
ansを返す
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const lli MOD = 1e9 + 7;
class Solution {
public:
lli add(lli a, lli b){
return (a % MOD + b % MOD) % MOD;
}
lli mul(lli a, lli b){
return (a % MOD * b % MOD) % MOD;
}
int sumSubarrayMins(vector<int>& A) {
stack <int> st;
int n = A.size();
vector <int> left(n, -1);
vector <int> right(n, n);
int ans = 0;
for(int i = 0; i < n; i++){
while(!st.empty() && A[st.top()] >= A[i]){
st.pop();
}
if(!st.empty())left[i] = st.top();
st.push(i);
}
while(!st.empty())st.pop();
for(int i = n - 1; i >= 0; i--){
while(!st.empty() && A[st.top()] > A[i]){
st.pop();
}
if(!st.empty())right[i] = st.top();
st.push(i);
}
for(int i = 0; i < n; i++){
int leftBound = i - (left[i] + 1);
int rightBound = (right[i] - 1) - i;
int contri = 1 + leftBound + rightBound + (leftBound * rightBound);
ans = add(ans, mul(contri, A[i]));
}
return ans;
}
};
main(){
vector<int> v = {3,1,2,4};
Solution ob;
cout << (ob.sumSubarrayMins(v));
} 入力
[3,1,2,4]
出力
17
-
C ++のプレフィックス合計を使用したO(n)の最大サブ配列合計
問題の説明 正の整数と負の整数の配列が与えられた場合、その配列の最大サブ配列の合計を求めます 例 入力配列が− {-12、-5、4、-1、-7、1、8、-3}の場合、出力は9 アルゴリズム 入力配列のプレフィックス合計を計算します。 Initialize− min_prefix_sum =0、res =-infinite i=0からnまでのループを維持します。 (nは入力配列のサイズです。) cand =prefix_sum [i] – mini キャンドの場合 がres(これまでのサブアレイの最大合計)より大きい場合は、resをcandで更新します。
-
C ++でのアリコートの合計?
ここで、アリコートの合計は何ですか? nのアリコート和は、nを除くnのすべての完全な因子の合計です。たとえば、数値が20の場合、完全な因数は(1、2、4、5、10)です。したがって、アリコートの合計は22です。 興味深い事実の1つは、ある数のアリコートの合計がその数そのものである場合、その数は完全数であるということです。たとえば、6。係数は(1、2、3)です。アリコートの合計は1+2 + 3=6です。 次のアルゴリズムを使用してアリコートの合計を取得する方法を見てみましょう。 アルゴリズム getAliquotSum(n) begin sum := 0 &nbs