待修莫队板子 P1903 [国家集训队]数颜色

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YewSpadeJ/article/details/81908401
//改不出来决定重写的带修莫队
// 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define Inf 0x3f3f3f3f
#define maxn 50010
#define maxm 1000010
using namespace std;
int n,m,block,a[maxn],ans[maxm],qnum,cnum,now,anss,anssq[maxn];
/*int read()
{
    int x=0,f=1;char ch=getchar(); 
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}*/


struct Q{
    int le,ri,num,ti;
    /*friend bool operator < (Q a, Q b) {
        if((a.le-1)/block != (b.le-1)/block) return (a.le-1)/block < (b.le-1)/block;
        if((a.ri-1)/block != (b.ri-1)/block) return (a.ri-1)/block < (b.ri-1)/block;
        return  a.ti < b.ti;} //重载运算符*/
        
}ques[maxm];
struct C{
    int poi,val;
}chan[maxm];
bool cmp(Q a,Q b){
    if((a.le-1)/block!=(b.le-1)/block)
    return (a.le-1)/block<(b.le-1)/block;
    if((a.ri-1)/block!=(b.ri-1)/block)
    return (a.ri-1)/block<(b.ri-1)/block;
    return a.ti<b.ti;
}
void add(int pos)
{
    ans[a[pos]]++;
    if(ans[a[pos]]==1)anss++;
    return;
}
void del(int pos)
{
    ans[a[pos]]--;
    if(ans[a[pos]]==0)anss--;
    return;
}
void ti_c(int T,int pos)
{
    if(chan[T].poi>=ques[pos].le&&chan[T].poi<=ques[pos].ri)
        {
            if(--ans[a[chan[T].poi]]==0)
                anss--;
            if(++ans[chan[T].val]==1)
                anss++;	
            }
    swap(a[chan[T].poi],chan[T].val);
    return;
}
void solve()
{
    int L=0,R=0,t_now=0;
    for(int i=1;i<=qnum;i++)
    {
        while(L<ques[i].le)del(L++);
        while(L>ques[i].le)add(--L);
        while(R>ques[i].ri)del(R--);
        while(R<ques[i].ri)add(++R);
        while(t_now<ques[i].ti)ti_c(++t_now,i);
        while(t_now>ques[i].ti)ti_c(t_now--,i);
        anssq[ques[i].num]=anss;//cout<<anss;
        }
    return ;
}
int main()
{
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    char x;
    for(int i=1;i<=m;i++)
    {
        cin>>x;
        if(x=='Q')
            {++qnum;ques[qnum].num=qnum,ques[qnum].ti=cnum;scanf("%d%d",&ques[qnum].le,&ques[qnum].ri);}
        else {++cnum;scanf("%d%d",&chan[cnum].poi,&chan[cnum].val);}
    }
        block=ceil(exp((log(n)+log(qnum))/3));
        sort(ques+1,ques+qnum+1,cmp);
        solve();
        for(int i=1;i<=qnum;i++)
        printf("%d\n",anssq[i]);		
    return 0;
}

猜你喜欢

转载自blog.csdn.net/YewSpadeJ/article/details/81908401
今日推荐