題解 不同的數列

2022-05-11 19:09:41 字數 1522 閱讀 6110

我們有乙個長度無窮的數列\(a[i]\),其中初始的時候只有數列前n項可能不為0,從第n+1項開始都為0。

我們可以做如下操作任意次。

選擇乙個\(i\)滿足\(a[i]>0\)且\(a[i+1]>0\), 然後將\(a[i]\)減\(1\),\(a[i+1]\)減\(1\),\(a[i+2]\)加\(1\)。

我們現在想要知道,通過任意次做這個操作,能得到多少種不同的數列。

兩個數列不同當且僅當這兩個數列存在乙個對應位置上的數不同。

答案非常大,輸出答案對\(1000000007\)取模。

(注意這個不同數列的個數要包括初始的數列,可通過樣例2理解)

第一行乙個整數n。

第二行n個整數,第i個整數代表a[i]。

輸出一行乙個整數表示方案數對1000000007取模的結果。

\(n\le 50,0\le a[i]\le 50\)

考慮最最最最最暴力的dp狀態設計,\(dp[a_i][a_]...[a_j]\)表示對於數列\(,...,a_,a_j,0,0,0,...}\)的答案。

發現\(dp[a_i][a_][a_][a_]...[a_j]\)可以轉移到\(dp[a_i-k][a_-k][a_+k][a_]...[a_j]\)。

其中,從\(a_\)到\(a_j\)都沒有變化,且為原數列\(a\)中連續的一段數,於是考慮優化。

用\(dp[x][y][z][k]\)表示對於數列\(,a_,...,a_,a_,0,0,0,...}\)的答案。

邊界條件:

轉移方程:

\[dp[x][y][z][k]=\sum_^dp[y-i][z+i][a[k]][k+1]

\]上述方案顯然會tle,於是考慮優化。

注意到dp陣列是四維的,相對較大。考慮改為三維。

顯然第四維非常重要不能刪,所以應把前三維維護三個數改為用兩維維護兩個數。

設\(dp[x][y][k]\)表示對於數列\(,a_,...,a_,a_,0,0,0,...}\)的答案。

下面討論問什麼只維護兩個數是可行的

由轉移方程可以看出每次轉移後考慮答案的區間會向右移動1,所以雖然操作對三個數有效,但區間向右平移後第三個數變成了第二個。

之所以最後一維的k可以表示\(,a_,...,a_,a_,0,0,0,...}\),是因為他們都是原數列中的數。第三個數在修改前也是原數列中的數所以可以用k表示

同樣的原因也可以發現我們至少要維護乙個數

只維護乙個數的話根本無法得知當前位置可以進行的操作次數

只維護第\(i\)個數時,由於在\(i-1\)處的操作(即a[i-1]-1,a[i]-1,a[i+1]+1),第\(i+1\)個數可能不是原陣列中的數,所以不能用k表示

暫缺\[dp[x][y][k]

\]由邊界條件2可知,第三維大小為 \(n+2\)。

顯然第一、二維的大小為數列中數的最大值。

數列中數的初始最大值為50,數列非零位最長長度為50,欲求若干次操作後最大值的上界,不妨假設

\[50+\frac(50+50)+\frac(50+50)+\frac(50+50)+...

\]

題解 Luogu P3901 數列找不同

塊數就直接取sqrt n 對所有詢問進行排序 考慮ai不大,暴力開陣列 add時如果加之後的數量是1 總數就加1 del時如果減之後的數量是0 總數就減1 每次比較總數和該次查詢區間的長度 相等的話就把 ans q i id 設為真 最後如果ans i 為真就輸出yes,否則輸出no pragma ...

數列找不同

題目描述 現有數列a 1,a 2,cdots,a na 1 a 2 a n q 個詢問 l i,r i l i r i a a cdots,a a li a li 1 a ri 是否互不相同 輸入格式 第1 行,2 個整數n,qn,q 第2 行,n 個整數a a cdots,a a li a li ...

數列找不同

現有數列a 1,a 2,cdots,a na1 a2 an q 個詢問 l i,r i li ri a a cdots,a ali ali 1 ari 是否互不相同 第1 行,2 個整數n,qn,q 第2 行,n 個整數a a cdots,a ali ali 1 ari q 行,每行2 個整數l i...