BZOJ 2120: The number of colors with a repair team Mo (Mo can be persistent team)

Creative Commons License Copyright: Attribution, allow others to create paper-based, and must distribute paper (based on the original license agreement with the same license Creative Commons )

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 T T , 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;
}

Guess you like

Origin blog.csdn.net/huashuimu2003/article/details/92066306