模板題位址
墨墨購買了一套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.排序以左端點所在的塊為第一關鍵字,右端點為第二關鍵字
structnode
}q[maxn];
感覺是不是暴力得讓人難以接受=、= , 就是好用!
然而話說回來這個題帶上了修改。
之前沒有修改我們排序的是乙個(l,r)
帶了修改就不妨加上一維時間軸,排序這個(l,r,t)
再按照樸素的方法做,問題就迎刃而解了。
#include#define maxn 10010using
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。為了滿足墨墨的要求,你知道你需要幹什麼了嗎?參考 額外維護乙個當前修改...