#### 題目:https://judge.tcirc.tw/ShowProblem?problemid=d101
這題n跟k都可以到很大,暴力解容易TLE
```C++=
#include <iostream>
#include <set>
using namespace std;
const int maxn = 100005;
int n, k, c[maxn], length[maxn], mx, mn;
multiset <int> st;
void change(int x){
length[x] = length[x-1] + length[x+1] + 1;
st.insert(length[x]);
if(length[x+1] != 0)
st.erase(st.find(length[x+1])); // 移除這段長度
length[x+length[x+1]] = length[x]; // 把頭尾改成長度
if(length[x-1] != 0)
st.erase(st.find(length[x-1]));
length[x-length[x-1]] = length[x];
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++){
cin >> c[i];
if (c[i] == 1){
change(i);
}
}
if(!st.empty()){
mx += *st.rbegin();
mn += *st.begin();
}
for (int i = 1; i <= k; i++){
int q;
c[q] = 1;
cin >> q;
change(q);
mx += *st.rbegin();
mn += *st.begin();
}
cout << mx << endl << mn;
}
```
### 逐步看length陣列發生什麼事情
這份程式的邏輯是
每填一個顏色就check前後,如果length不等於0就代表要連接,並從multiset中erase掉那一段長度
從範例輸入來看各陣列和集合的變化可能會比較好理解
```
9 3
0 1 1 0 0 1 0 1 0
5 1 7
```
c 陣列負責儲存彩帶顏色資料
length 陣列儲存他們的長度訊息
st 儲存彩帶的長度
(下面length用l表示)
- ### 一開始全都是白色
```
c : 0 0 0 0 0 0 0 0 0
l : 0 0 0 0 0 0 0 0 0
st = {}
```
- ### cin 第一個 1
```
c : 0 1 0 0 0 0 0 0 0
l : 0 1 0 0 0 0 0 0 0
st = {1}
```
- ### cin 第二個 1
cin後進入change函式,發現前一個的length是1,所以自己的length變成1+1=2
```
c : 0 1 1 0 0 0 0 0 0
l : 0 2 2 0 0 0 0 0 0
st = {2}
```
- ### cin 第三個 1
```
c : 0 1 1 0 0 1 0 0 0
l : 0 2 2 0 0 1 0 0 0
st = {1, 2}
```
- ### cin 第三個 1
```
c : 0 1 1 0 0 1 0 1 0
l : 0 2 2 0 0 1 0 1 0
st = {1, 1, 2}
```
- ### 第一個填色(5)
```
c : 0 1 1 0 1 1 0 1 0
l : 0 2 2 0 2 2 0 1 0
st = {1, 2, 2}
```
- ### 第二個填色(1)
```
c : 1 1 1 0 1 1 0 1 0
l : 3 2 3 0 2 2 0 1 0
st = {1, 2, 3}
```
- ### 第三個填色(7)
```
c : 1 1 1 0 1 1 1 1 0
l : 3 2 3 0 4 2 4 4 0
st = {3, 4}
```
每段彩帶的頭尾都會變成那段彩帶的長度