模板 分塊 可修改莫隊 數顏色種類

2022-03-27 07:33:02 字數 1519 閱讀 9147

模板題位址

墨墨購買了一套n支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會像你發布如下指令:

1、 q l r代表詢問你從第l支畫筆到第r支畫筆中共有幾種不同顏色的畫筆。

2、 r p col 把第p支畫筆替換為顏色col。

為了滿足墨墨的要求,你知道你需要幹什麼了嗎?

範圍n,m <=10000   每個數都<=10^6

剛學會莫隊就說說莫隊:一種離線處理詢問區間的好辦法,雖然看上去超級暴力,但是很快。

把詢問按左右端點排序,每次移動兩個端點在o(1)的時間內更新答案即可。

while(l/*

o(1)更新答案

*/l++;}

while(l>q[i].l)

while(r/*

o(1)更新答案*/}

while(r>q[i].r)

當然還要用到分塊的優化。

p.s.排序以左端點所在的塊為第一關鍵字,右端點為第二關鍵字

struct

node

}q[maxn];

感覺是不是暴力得讓人難以接受=、=  , 就是好用!

然而話說回來這個題帶上了修改。

之前沒有修改我們排序的是乙個(l,r)

帶了修改就不妨加上一維時間軸,排序這個(l,r,t)

再按照樸素的方法做,問題就迎刃而解了。

#include#define maxn 10010

using

namespace

std;

int n,m,q,siz,tim,a[maxn],belong[maxn],ans[maxn],color[100010

],tmp;

struct

node

else

return belong[l]}

}q[maxn];

struct

changec[maxn];

void change(int now,int

i) swap(a[c[now].x],c[now].y);

}int

main()

;

else c[++tim]=(change);

}sort(q+1,q+q+1

);

int l=0,r=0,now=0

;

for(int i=1;i<=q;i++)

while(l>q[i].l)

while(rif(color[a[r]]==1)tmp++;}

while(r>q[i].r)

while(now;change(now,i);}

while(now>q[i].t)

ans[q[i].id]=tmp;

}for(int i=1;i<=q;i++)

printf(

"%d\n

",ans[i]);

return0;

}

bzoj 2120 數顏色(單點修改莫隊)

普通不帶修改的莫隊是對詢問二元組 l,r l,r l,r 進行分塊排序以降低複雜度 對於單點修改的莫隊,引入乙個時間座標 t,詢問變成三元組 l,r,t l,r,t l,r,t 每一步 l,r,t l,r,t l,r,t 有6個方向可走 用類似普通莫隊的分塊方法,對 l,r 以 n23 n n3 2...

Luogu P1903數顏色(帶修改莫隊)

題目鏈結 帶修改莫隊模板。加乙個變數記錄現在是第幾次修改,看看當前列舉的詢問是第幾次修改,改少了就改過去,改多了就改回來。話說我棧用成佇列了能過樣例?include include include include include include include define maxn 50000 u...

bzoj 2120 數顏色 帶修改莫隊

墨墨購買了一套n支彩色畫筆 其中有些顏色可能相同 擺成一排,你需要回答墨墨的提問。墨墨會向你發布如下指令 1 q l r代表詢問你從第l支畫筆到第r支畫筆中共有幾種不同顏色的畫筆。2 r p col 把第p支畫筆替換為顏色col。為了滿足墨墨的要求,你知道你需要幹什麼了嗎?參考 額外維護乙個當前修改...