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