1. 程式人生 > >bzoj 2120: 數顏色

bzoj 2120: 數顏色

莫隊 acc pac scu nod data lan class out

Time Limit: 6 Sec Memory Limit: 259 MB
Submit: 6905 Solved: 2789
[Submit][Status][Discuss]

Description

墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會像你發布如下指令: 1、 Q L R代表詢問你從第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。 2、 R P Col 把第P支畫筆替換為顏色Col。為了滿足墨墨的要求,你知道你需要幹什麽了嗎?

Input

第1行兩個整數N,M,分別代表初始畫筆的數量以及墨墨會做的事情的個數。第2行N個整數,分別代表初始畫筆排中第i支畫筆的顏色。第3行到第2+M行,每行分別代表墨墨會做的一件事情,格式見題幹部分。

Output

對於每一個Query的詢問,你需要在對應的行中給出一個數字,代表第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。

Sample Input

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6

Sample Output

4
4
3
4

HINT

對於100%的數據,N≤10000,M≤10000,修改操作不多於1000次,所有的輸入數據中出現的所有整數均大於等於1且不超過10^6。


2016.3.2新加數據兩組by Nano_Ape

普通的莫隊是二維的,而帶修改的莫隊改成三維的就行了,把範圍最小的一維放到最後(比如本題是時間),隨便暴力即可。 (不知道為什麽在bzoj A了然而在洛谷造的dark數據90)
/*
************************************************************* Problem: 2120 User: JYYHH Language: C++ Result: Accepted Time:796 ms Memory:5520 kb ****************************************************************/ #include<bits/stdc++.h> #define ll long long #define maxn 10005 using
namespace std; struct node{ int l,r,num,bl,tim; }q[maxn]; bool cmp2(node x,node y){ return (x.bl&1)?(x.r==y.r?x.tim>y.tim:x.r<y.r):(x.r==y.r?x.tim<y.tim:x.r>y.r); } bool cmp1(node x,node y){ return (x.bl==y.bl?cmp2(x,y):x.bl<y.bl); } struct ch{ int pos,from,to; }up[3005]; int a[maxn],n,m,qnum,cnum; int ans[maxn],sz,uu,vv; int col[1000005],tot=0; int le=1,ri,t; char c; inline void add(int x){ if((++col[a[x]])==1) tot++; } inline void del(int x){ if(!(--col[a[x]])) tot--; } inline void tadd(int p){ ch x=up[p]; if(x.pos>=le&&x.pos<=ri){ col[x.from]--,col[x.to]++; if(!col[x.from]) tot--; if(col[x.to]==1) tot++; } a[x.pos]=x.to; } inline void tdel(int p){ ch x=up[p]; if(x.pos>=le&&x.pos<=ri){ col[x.from]++,col[x.to]--; if(col[x.from]==1) tot++; if(!col[x.to]) tot--; } a[x.pos]=x.from; } int main(){ scanf("%d%d",&n,&m); sz=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=m;i++){ c=getchar(); while(c!=Q&&c!=R) c=getchar(); scanf("%d%d",&uu,&vv); if(c==Q) q[++qnum]=(node){uu,vv,qnum,(uu-1)/sz+1,cnum}; else up[++cnum]=(ch){uu,a[uu],vv},a[uu]=vv; } sort(q+1,q+qnum+1,cmp1); t=cnum; for(int i=1;i<=qnum;i++){ while(le<q[i].l) del(le),le++; while(ri<q[i].r) ri++,add(ri); while(le>q[i].l) le--,add(le); while(ri>q[i].r) del(ri),ri--; while(t<q[i].tim) t++,tadd(t); while(t>q[i].tim) tdel(t),t--; ans[q[i].num]=tot; } for(int i=1;i<=qnum;i++) printf("%d\n",ans[i]); return 0; }

bzoj 2120: 數顏色