[2021-09-11 CQBZ/HSZX多校联考 T1] 茅山道术 (后缀和优化dp)
茅山道術
- description
- solution
- code
description
題目描述
小七擅長茅山道術,有一天他發現了 n 個排成一行的寶石,其中第 i 個寶石
有一個顏色 ci 。
小七決定用茅山道術替換一些寶石,具體地,他每次施法可以選定兩個滿足
cl = cr 的正整數 l; r(1 ≤ l ≤ r ≤ n) ,然后將區間 [l; r] 內的寶石全部替換為顏
色為 cl 的寶石。
小七想知道,在經過若干次施法后(可以一次也不施法),最終能形成多少
種可能的顏色序列呢?
兩個序列不同等價于存在一個 i ,使得位置 i 的寶石在兩個序列中顏色不
同。由于答案可能很大,你只需要輸出答案對 109 + 7 取模的結果。
輸入格式
輸入文件 magic.in 包含 2 行。
第 1 行輸入一個正整數表示 n 。
第 2 行輸入 n 個正整數,其中第 i 個正整數表示 ci 。
輸出格式
輸出文件 magic.out 包含一行,僅一個非負整數,表示答案對 109 + 7 取模
的結果。
樣例輸入
6
1 2 1 3 4 3
樣例輸出
4
數據范圍及約定
| 1 ~ 4 | ≤ 5 | 無 |
| 5 ~ 10 | ≤ 2 × 103 | 無 |
| 11 ~ 14 | ≤ 106 | ci ≤ 2 |
| 15 ~ 20 | ≤ 106 | 無 |
對于 100% 的數據,滿足 1 ≤ k ≤ n ≤ 106; 1 ≤ ci ≤ n
solution
case 1~4 :隨便暴力
case 11~14 :具有特殊性質1≤ci≤21\le c_i\le 21≤ci?≤2
通過找規律(也可以證明),答案為nnn對應的斐波拉契數
case 5~10 :n≤2000n\le 2000n≤2000
前面的數據點只是為了不讓做不出來的人難看罷了,只有這個數據點是設置的與正解有關的
顯然可以承擔n2n^2n2的dpdpdp,設fi:[i,n]f_i:[i,n]fi?:[i,n]的序列有多少種
暴力枚舉iii可以和哪些j(i<j)j(i<j)j(i<j)匹配,即fi=∑j=i+1n[ci=cj]fj+1f_i=\sum_{j=i+1}^n[c_i=c_j]f_j+1fi?=∑j=i+1n?[ci?=cj?]fj?+1(不匹配,保持原序列不變)
case 15~20 :n≤106,1≤ci≤nn\le 10^6,1\le c_i\le nn≤106,1≤ci?≤n
想辦法在比較暴力的dpdpdp基礎上優化掉一個nnn
發現對于iii有用的只有和其顏色相同的jjj,每個iii都會累加后面的所有與之顏色相同的jjj的答案
這其實是個后綴和的形式,后綴和優化,即gc:g_c:gc?: 到iii為止顏色為ccc的所有j(i<j)j(i<j)j(i<j)的fff之和
每次求完fif_ifi?后,再對gcig_{c_i}gci??進行更新
時間復雜度O(n)O(n)O(n)
還不用對顏色離散化,代碼就更簡單了
code
#include <cstdio> #define maxn 1000005 #define int long long #define mod 1000000007 int n; int c[maxn], f[maxn], g[maxn];signed main() {freopen( "magic.in", "r", stdin );freopen( "magic.out", "w", stdout );scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) {scanf( "%lld", &c[i] );if( c[i] == c[i - 1] ) i --, n --;}f[n + 1] = 1;for( int i = n;i;i -- ) {f[i] = ( f[i + 1] + g[c[i]] ) % mod;g[c[i]] = ( g[c[i]] + f[i + 1] ) % mod;}printf( "%lld\n", f[1] );return 0; }總結
以上是生活随笔為你收集整理的[2021-09-11 CQBZ/HSZX多校联考 T1] 茅山道术 (后缀和优化dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 360免费电话是什么?360免费电话的使
- 下一篇: 安卓地铁跑酷下载(安卓地铁跑酷)