[莫队] 国家集训队 数颜色(尚未完成)

题目描述

墨墨购买了一套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。

本题可能轻微卡常数

题解

  • 带修改莫队裸题
    ```cpp

    include

    include

    include

    include

    include

    include

    include

    define in(i) (i=read())

    using namespace std;
    typedef long long lol;
    lol read()
    {
    lol ans=0,f=1;
    char i=getchar();
    while(i<'0'||i>'9')
    {
    if(i=='-') f=-1;
    i=getchar();
    }
    while(i>='0'&&i<='9')
    {
    ans=(ans<<3)+(ans<<1)+i-'0';
    i=getchar();
    }
    return ans*f;
    }
    struct query
    {
    lol l,r,id,pos,pre;
    }e[200010];
    struct chang
    {
    lol pos,val;
    }q[200010];
    lol c[500010];
    lol cnt[1000010];
    lol ans[200010];
    lol tot,qnum,cnum;
    lol n,m;
    lol cmp(query a,query b)
    {
    if(a.pos!=b.pos) return a.pos<b.pos;
    if(a.r!=b.r) return a.r<b.r;
    return a.pre<b.pre;
    }
    void add(lol x)
    {
    cnt[c[x]]++;
    if(cnt[c[x]]==1) tot++;
    }
    void remove(lol x)
    {
    cnt[c[x]]--;
    if(cnt[c[x]]==0) tot--;
    }
    void work(int now,int i)
    {
    if(q[now].pos>=e[i].l && q[now].pos<=e[i].r)
    {
    if(--cnt[c[q[now].pos]]==0) tot--;
    if(++cnt[q[now].val]==1) tot++;
    }
    swap(q[now].val,c[q[now].pos]);
    }
    void solve()
    {
    for(lol i=1,curl=1,curr=0,now=0;i<=qnum;i++)
    {
    lol l=e[i].l,r=e[i].r;
    while(curl l) add(--curl);
    while(curr r) remove(curr--);
    while(now e[i].pre) work(now--,i);
    ans[e[i].id]=tot;
    }
    for(lol i=1;i<=qnum;i++)
    {
    printf("%lld\n",ans[i]);
    }
    }
    int main()
    {
    in(n);in(m);
    lol block=(lol)sqrt(n);
    for(lol i=1;i<=n;i++) in(c[i]);
    for(lol i=1;i<=m;i++)
    {
    char ch;
    cin>>ch;
    if(ch=='Q')
    {
    in(e[++qnum].l);in(e[qnum].r);
    e[qnum].id=qnum;
    e[qnum].pos=(e[qnum].l-1)/block+1;
    e[qnum].pre=cnum;
    }
    else
    {
    in(q[++cnum].pos);in(q[cnum].val);
    }
    }
    sort(e+1,e+1+qnum,cmp);
    solve();
    return 0;
    }

```

猜你喜欢

转载自www.cnblogs.com/real-l/p/9210936.html