一直想学这个算法,但是没有碰见类似的于是就作罢
今天忽然看到这道题有点感觉,搞一搞
感觉带修莫队其实不是特别深奥难懂的
只是在原有的基础上加了一个时间轴
我比较喜欢在struct里面写重载
struct Mo { int l,r,t,id; bool operator<(const Mo &a) const { if (a.l/size==l/size) { if (a.r/size==r/size) return t<a.t; return r<a.r; } return l<a.l; } } q[N];
这样就排好序了,大致的也没啥,直接上代码看看就很容易懂的哦
#include<bits/stdc++.h> using namespace std; const int N=1e6+7; int m,n,k,size,res,qnum,cnum,inc; int cnt[N],ans[N],a[N]; struct Mo { int l,r,t,id; bool operator<(const Mo &a) const { if (a.l/size==l/size) { if (a.r/size==r/size) return t<a.t; return r<a.r; } return l<a.l; } } q[N]; struct change { int pos,val; } c[N]; void change(int now,int t) { if (c[now].pos>=q[t].l&&c[now].pos<=q[t].r) { cnt[a[c[now].pos]]--; if (cnt[a[c[now].pos]]==0) inc--; if (cnt[c[now].val]==0) inc++; cnt[c[now].val]++; } swap(a[c[now].pos],c[now].val); } int main() { scanf("%d%d",&n,&m); size=pow(n,2.0/3.0); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=m;i++) { int x,y;char op[5]; scanf("%s%d%d",op,&x,&y); if (op[0]=='Q') { qnum++;q[qnum].l=x;q[qnum].r=y;q[qnum].id=qnum;q[qnum].t=cnum; } else { cnum++;c[cnum].pos=x;c[cnum].val=y; } } sort(q+1,q+qnum+1); int l=0,r=0,now=0; for (int i=1;i<=qnum;i++) { while (l>q[i].l) {l--;if (cnt[a[l]]==0) inc++;cnt[a[l]]++;} while (l<q[i].l) {cnt[a[l]]--;if (cnt[a[l]]==0) inc--;l++;} while (r>q[i].r) {cnt[a[r]]--;if (cnt[a[r]]==0) inc--;r--;} while (r<q[i].r) {r++;if (cnt[a[r]]==0) inc++;cnt[a[r]]++;} while (now>q[i].t) {change(now,i);now--;} while (now<q[i].t) {now++;change(now,i);} ans[q[i].id]=inc; } for (int i=1;i<=qnum;i++) printf("%d ",ans[i]); return 0; }