Luogu P1903 [国家集训队]数颜色 or 维护队列

标准的带修莫队。。。咕到了现在$qwq$


 

莫队是对询问排序来优化复杂度的(不带修就是对询问区间$[l,r]$排序)。。

那么现在带修了,我们再可以维护一个时间维度$tm$:对于每个询问,每次回答前先检查时间指针是否与询问的时间对应,不对应则按操作时间修改。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ull unsigned long long
#define ll long long
#define R register int
#define pause (for(R i=1;i<=10000000000;++i))
#define OUT freopen("out.out","w",stdout);
using namespace std;
namespace Fread {
    //static char B[1<<15],*S=B,*D=B;
    //#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } inline bool isempty(const char& ch) {return ch<=36||ch>=127;}
    inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
}using Fread::g; using Fread::gs;
const int M=50010;
int n,m,T,tim,cl[M*100],cnt,cntq,a[M],crt[M],pos[M],ans[M],anss,l=1,r=0;
struct node { int l,r,tm,rk;
    inline bool operator <(const node& that) {
        return pos[l]==pos[that.l]?(pos[r]==pos[that.r]?tm<that.tm:(pos[l]&1)?r<that.r:r>that.r):l<that.l;
        //return pos[l]==pos[that.l]?(pos[r]==pos[that.r]?tm<that.tm:r<that.r):l<that.l;
    } 
    #define l(i) s[i].l
    #define r(i) s[i].r
    #define tm(i) s[i].tm
    #define rk(i) s[i].rk
}s[M];
struct que{int pos,nw,od;}q[M];
inline void change(int pos,int inc) {inc>0?anss+=(++cl[pos]==1):anss-=(--cl[pos]==0);}
inline void upd(int pos,int nw) {
    if(pos>=l&&pos<=r) change(a[pos],-1),change(nw,1); a[pos]=nw;
}
signed main() {
#ifdef JACK
    freopen("NOIPAK++.in","r",stdin);
#endif
    n=g(),m=g(); T=pow(n,2.0/3);
    for(R i=1;i<=n;++i) a[i]=g(); memcpy(crt,a,sizeof(int)*(n+1));
    for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1;
    for(R i=1;i<=m;++i) { register char ch; while(!isalpha(ch=getchar()));
        R l=g(),r=g(); if(ch=='Q') l(++cnt)=l,r(cnt)=r,tm(cnt)=cntq,rk(cnt)=cnt;
        else q[++cntq].pos=l,q[cntq].nw=r,q[cntq].od=crt[l],crt[l]=r;
    } sort(s+1,s+cnt+1); for(R i=1;i<=m;++i) {
        while(tim<tm(i)) ++tim,upd(q[tim].pos,q[tim].nw);
        while(tim>tm(i)) upd(q[tim].pos,q[tim].od),--tim;
        while(l<l(i)) change(a[l],-1),++l;
        while(l>l(i)) change(a[--l],1);
        while(r<r(i)) change(a[++r],1);
        while(r>r(i)) change(a[r],-1),--r;
        ans[rk(i)]=anss;
    } for(R i=1;i<=cnt;++i) printf("%d\n",ans[i]);
}

2019.07.03

 

posted @ 2019-07-03 16:28  LuitaryiJack  阅读(164)  评论(0编辑  收藏  举报