time limit: 6 sec
memory limit: 259 mb
submit: 6031
solved: 2392 [
submit][
status][
discuss]
墨墨購買了一套n支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會像你發布如下指令: 1、 q l r代表詢問你從第l支畫筆到第r支畫筆中共有幾種不同顏色的畫筆。 2、 r p col 把第p支畫筆替換為顏色col。為了滿足墨墨的要求,你知道你需要幹什麼了嗎?
第1行兩個整數n,m,分別代表初始畫筆的數量以及墨墨會做的事情的個數。第2行n個整數,分別代表初始畫筆排中第i支畫筆的顏色。第3行到第2+m行,每行分別代表墨墨會做的一件事情,格式見題幹部分。
對於每乙個query的詢問,你需要在對應的行中給出乙個數字,代表第l支畫筆到第r支畫筆中共有幾種不同顏色的畫筆。
6 51 2 3 4 5 5
q 1 4
q 2 6
r 1 2
q 1 4
q 2 644
34對於100%的資料,n≤10000,m≤10000,修改操作不多於1000次,所有的輸入資料中出現的所有整數均大於等於1且不超過10^6。
又是一道緊張刺激的bzoj
單點更新,區間查詢
每次查詢區間內有多少個不同的數字
可以說是 poj 2777 的公升級版
當顏色過少的時候,可以狀壓顏色,這樣就能用線段樹
但是這題顏色很多
「反正資料結構題就是xjb維護乙個區間啦」
—— 來自某資料結構大佬的指點
很明顯原區間根據我現在的能力不太好維護
所以我們考慮換過乙個區間
olast[i] 表示第 i 個元素上次出現的位置
所以對於區間 [l, r] ,如果olast[i] < l, 就說明只出現過一次
所以問題就變成了
多次 單點更新,區間查詢
每次查詢 [l. r] 中小於 l 的數字有多少個
然後就是分塊
查詢的時候
對於每個不完整的塊暴力查詢
對於完整的塊
對塊的資訊進行排序
然後可以二分查詢
修改的時候感覺有點麻煩
你需要重構olast
重構過程中如果有塊的內容發生改變
那麼我們就重構塊
複雜度。。。
每次查詢是 num * log(sqrt(n))
每次更新是num * sqrt(n) * log(sqrt(n)) (花在排序上)
似乎最優塊的大小是 (sqrt(n)+log(2*n)/log(2)) 應該是根據複雜度算的?
但好像沒有快多少
#include using namespace std;
const int n = 100010;
const int m = 1000010;
int ma[n];
//int mb[n];
int bl[n]; ///belong
int wl[n];///塊的左邊界
int wr[n];///塊的右邊界
int pre[n];///排序後的塊資訊
int nlast[m]; ///數字 i 最後出現在第 last[i] 處
int olast[n]; ///第 i 個數字最後出現在第 last[i] 處
int block;
int num;
int n, m;
void build()
for(int i = 1; i <= n; i ++)
for(int i = 1; i <= num; i ++)
wr[num] = n;
for(int i = 1; i <= num; i ++)
sort(pre + wl[i], pre + wr[i] + 1);
}}int query(int ll, int rr)}}
else
}for(int i = bl[ll] + 1; i < bl[rr]; i ++)
for(int i = wl[bl[rr]]; i <= rr; i ++)}}
return ans;
}void update(int x, int v)
ma[x] = v;
for(int i = 1; i <= num; i ++)
olast[j] = nlast[ma[j]];
nlast[ma[j]] = j;
}if(mark)
sort(pre + wl[i], pre + wr[i] + 1);}}
}int main()
build();
for(int i = 0; i < m; i ++)
else}}
}
bzoj2120 數顏色 分塊
據說暴力可過2200ms。然而我寫分塊也才1200ms。然而很多人寫分塊跑不過暴力。參考了將狼踩盡 的思路。假設分為m塊 注意不是每塊m個 用sum x y z 表示在塊x y中顏色z 經過離散化以後 的個數,val x y 表示在x y塊中不同顏色的個數。這樣應該就比較容易明白了。修改 看u會影響...
bzoj 2120 數顏色 (分塊做法)
此篇文章主要講修改操作 用pre i 表示第i個元素的前乙個相同元素的位置,問題變成在區間 l,r 裡找大於l的數的個數,具體什麼意思去其他地方看 預設值為最大值。用ppp i 表示顏色i最後出現的位置 針對這道題顏色最多1e6種,建乙個1e6的陣列即可 color i 表示第i個位置是什麼顏色 總...
BZOJ 2120 數顏色 莫隊
題目傳送門 觀察前兩題,莫隊演算法好像是一種只支援查詢的離線演算法,但是莫隊真的不支援修改嗎?答案當然是否定的 莫隊是一種支援查詢和修改的離線演算法。就是一種優美的暴力 考慮在莫隊演算法中增加乙個變數no w 表示當前有no w 個修改已經修改掉了。並在每乙個詢問中增加乙個變數pr e 表示最近的修...