BZOJ 2120 數顏色 分塊

2021-08-09 07:16:31 字數 2451 閱讀 9850

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 表示最近的修...