带修莫队

Posted profish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带修莫队相关的知识,希望对你有一定的参考价值。

https://www.luogu.org/problemnew/show/P1903

 

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e6+8;
typedef long long LL;
typedef unsigned long long ULL;
//typedef pair<LL,LL> P;
const LL mod=1e9+7;
using namespace std;
int num[maxn],a[maxn],now[maxn];
char s[10];
int di;
struct up{
    int st,last,r;
}ch[maxn];
int res[maxn];
struct node{
    int l,r,k,id;
}q[maxn];
bool cmp(node u,node v){
    if(u.l/di!=v.l/di) return u.l/di<v.l/di;
    if(u.r/di!=v.r/di) return u.r/di<v.r/di;
    return u.k<v.k;
}
int nl,nr,nk,ans;
int query(int l,int r,int k){
    while(nl<l){
        num[now[nl]]--;
        if(num[now[nl]]==0){
            ans--;
        }
        nl++;
    }
    while(nl>l){
        nl--;
        if(num[now[nl]]==0){
            ans++;
        }
        num[now[nl]]++;
    }
    while(nr<r){
        nr++;
        if(num[now[nr]]==0){
            ans++;
        }
        num[now[nr]]++;

    }
    while(nr>r){
        num[now[nr]]--;
        if(num[now[nr]]==0){
            ans--;
        }
        nr--;
    }
    while(nk>k){
        if(ch[nk].st>=l&&ch[nk].st<=r){
            num[now[ch[nk].st]]--;
            if(num[now[ch[nk].st]]==0) ans--;
            num[ch[nk].last]++;
            if(num[ch[nk].last]==1) ans++;
        }
        now[ch[nk].st]=ch[nk].last;
        nk--;
    }
    while(nk<k){
        nk++;
        if(ch[nk].st>=l&&ch[nk].st<=r){
            num[now[ch[nk].st]]--;
            if(num[now[ch[nk].st]]==0) ans--;
            num[ch[nk].r]++;
            if(num[ch[nk].r]==1) ans++;
        }
        now[ch[nk].st]=ch[nk].r;
    }
    return ans;
}
int main(){
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        now[i]=a[i];
    }
    int tot=0,cnt=0;
    for(int i=1;i<=m;i++){
        scanf("%s%d%d",s,&x,&y);
        if(s[0]==Q){
            q[++cnt].l=x;
            q[cnt].r=y;
            q[cnt].k=tot;
            q[cnt].id=cnt;
        }
        else{
            ch[++tot].st=x;
            ch[tot].last=now[x];
            now[x]=y;
            ch[tot].r=y;
        }
    }
    for(int i=1;i<=n;i++){
        now[i]=a[i];
    }
    di=ceil(exp((log(n)+log(tot))/3));
    sort(q+1,q+cnt+1,cmp);
    nl=1;
    nr=0;
    nk=0;
    ans=0;
    for(int i=1;i<=cnt;i++){
        res[q[i].id]=query(q[i].l,q[i].r,q[i].k);
    }
    for(int i=1;i<=cnt;i++){
        printf("%d\n",res[i]);
    }
}

 

以上是关于带修莫队的主要内容,如果未能解决你的问题,请参考以下文章

带修莫队

莫队 + 带修莫队

2120: 数颜色(带修莫队)

Machine Learning(带修莫队)

带修莫队板子

带修莫队模版