[國家集訓隊]數顏色 / 維護佇列 洛谷p1903
阿新 • • 發佈:2018-11-02
題目描述
墨墨購買了一套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支畫筆中共有幾種不同顏色的畫筆。
輸入輸出樣例
輸入樣例#1: 複製
6 5 1 2 3 4 5 5 Q 1 4 Q 2 6 R 1 2 Q 1 4 Q 2 6
輸出樣例#1: 複製
4 4 3 4
說明
對於100%的資料,N≤50000,M≤50000,所有的輸入資料中出現的所有整數均大於等於1且不超過10^6。
本題可能輕微卡常數
來源:bzoj2120
本題資料為洛谷自造資料,使用CYaRon耗時5分鐘完成資料製作。
#include<bits/stdc++.h> #define f(i,l,r) for(i=(l);i<=(r);i++) using namespace std; const int MAXN=5000000; int n,m; int Base,qnum,cnum; int a[MAXN],Bel[MAXN]; int lcur=1,rcur,cur; int ans[MAXN],res; int num[MAXN]; struct Que{ int l,r,pre,id; }q[MAXN]; struct Cha{ int pos,w; }c[MAXN]; string s; bool cmp(Que a,Que b) { if(Bel[a.l]==Bel[b.l]&&Bel[a.r]==Bel[b.r]) return a.pre<b.pre; if(Bel[a.l]==Bel[b.l]) return a.r<b.r; return a.l<b.l; } void add(int pos) { if(++num[a[pos]]==1) res++; } void del(int pos) { if(--num[a[pos]]==0) res--; } inline void work(int cpos,int qpos) { if(c[cpos].pos>=q[qpos].l&&c[cpos].pos<=q[qpos].r){ if(--num[a[c[cpos].pos]]==0) res--; if(++num[c[cpos].w]==1) res++; } swap(a[c[cpos].pos],c[cpos].w); } int main() { ios::sync_with_stdio(false); int i,j; cin>>n>>m; Base=sqrt(n); f(i,1,n){ cin>>a[i]; Bel[i]=(i-1)/Base+1; } f(i,1,m){ cin>>s; if(s=="Q"){ qnum++; cin>>q[qnum].l>>q[qnum].r; q[qnum].id=qnum; q[qnum].pre=cnum; // cout<<q[qnum].l<<" "<<q[qnum].r<<"GG"<<endl; } else{ cnum++; cin>>c[cnum].pos>>c[cnum].w; } } // f(i,1,qnum) cout<<q[i].l<<" "<<q[i].r<<endl; sort(q+1,q+1+qnum,cmp); f(i,1,qnum){ while(lcur<q[i].l) del(lcur++); while(lcur>q[i].l) add(--lcur); while(rcur<q[i].r) add(++rcur); while(rcur>q[i].r) del(rcur--); while(cur<q[i].pre) work(++cur,i); while(cur>q[i].pre) work(cur--,i); ans[q[i].id]=res; // cout<<q[i].id<<" "<<q[i].l<<" "<<q[i].r<<" "<<res<<"GGG"<<endl; } f(i,1,qnum){ cout<<ans[i]<<endl; } return 0; }