title
BZOJ 2120
LUOGU 1903
Description
Ink ink bought a N branch color brush (some of which may be the same color), placed in a row, you need to answer questions ink ink. Ink ink will like you to publish the following instructions: 1, QLR ask you on behalf of a total of brush several different colors of brushes from L to R brushes in the first. 2, RP Col brushes replace the color of P Col. In order to meet the requirements of ink in the ink, you know you need to do it?
Input
Line 1 two integers N, M, representing the number of the initial number of ink in the ink pen and do things. Row 2 N integers, representing the initial i-th row branched brush pen color. The third row to the 2 + M rows, each row representing the ink in the ink will do a thing, formatted as casual working portion.
Output
For each query Query, you need to give a number in the corresponding row, L represents the brushes to a total of R brushes brush several different colors.
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
To 100% of the data, N≤10000, M≤10000, modify the operation more than 1000, all integers appearing all input data are not less than 1 and not more than 10 ^ 6.
2016.3.2 add new data sets by Nano_Ape
analysis
First on Reference: "the whole network the most detailed, most of the four categories of Mo algorithm team to explain" .
We found Mo ordinary team generally can not be changed, it is not too tasteless, and thus, have come up with a big brother Mo repair team, or thought that eight words: inquiry ordered pointer bounce . Just one more pointer , period pointers only.
So we sort of became: to inquire about the number of points where the block to the left end of the first key, the right end of the size of the second key to the node for the third time keyword sort. Then as Chairman tree advanced data structures such as records about the history of each version of the information can be.
Specific references to see it.
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e4+10,maxcol=1e6+1;
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
template<typename T>inline void write(T x)
{
if (!x) { putchar('0'); return ; }
if (x<0) putchar('-'), x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) putchar(ch[num--]);
}
struct Orz{int l,r,t,id,ans;}q[maxn];
int belong[maxn];
inline bool cmp1(Orz a,Orz b)
{
return belong[a.l]^belong[b.l]?a.l<b.l:(belong[a.r]^belong[b.r]?a.r<b.r:a.t<b.t);
}
inline bool cmp2(Orz a,Orz b)
{
return a.id<b.id;
}
int color[maxcol],ans;
inline void revise(int col,int opt)
{
color[col]+=opt;
if (opt>0) ans+=(color[col]==1)?1:0;
else ans-=(color[col]==0)?1:0;
}
int a[maxn],now[maxn],l=1,r=0,t=0,Tim,T;
inline void doit(int pos,int col)
{
if (l<=pos && pos<=r) revise(col,1),revise(a[pos],-1);
a[pos]=col;
}
struct QWQ{int pos,Old,New;}c[maxn];
int main()
{
int n,m;
read(n);read(m);
int block=floor(pow(n,2.0/3));
for (int i=1; i<=n; ++i) read(a[i]),now[i]=a[i],belong[i]=(i-1)/block+1;
for (int i=1,x,y; i<=m; ++i)
{
char ch=getchar();
read(x);read(y);
if (ch=='Q') q[++T]=(Orz){x,y,Tim,T};
else c[++Tim]=(QWQ){x,now[x],y},now[x]=y;
}
sort(q+1,q+T+1,cmp1);
for (int i=1; i<=T; ++i)
{
while (t<q[i].t) ++t,doit(c[t].pos,c[t].New);
while (t>q[i].t) doit(c[t].pos,c[t].Old),--t;
while (l<q[i].l) revise(a[l++],-1);
while (l>q[i].l) revise(a[--l],1);
while (r<q[i].r) revise(a[++r],1);
while (r>q[i].r) revise(a[r--],-1);
q[i].ans=ans;
}
sort(q+1,q+T+1,cmp2);
for (int i=1; i<=T; ++i) write(q[i].ans),puts("");
return 0;
}