莫队算法是离线算法,不支持修改,强制在线需要另寻他法。的确,遇到强制在线的题目莫队基本上萎了,但是对于某些允许离线的带修改区间查询来说,莫队还是能大展拳脚的。
讲解:https://www.cnblogs.com/WAMonster/p/10118934.html
https://blog.csdn.net/qq_45458915/article/details/106958683
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N=1e5+10;
int size,cntq,cntc;ll now;
int a[N],sum[N],cnt[N*15];
ll ans[N];
struct query{int l,r,t,id;bool operator<(const query& a)const{if(l/size!=a.l/size)return l<a.l;else if(r/size!=a.r/size)return r<a.r;elsereturn t<a.t;}
}q[N];
struct change{int x;
}c[N];void del(int x)
{now-=(--cnt[sum[x]]);
}
void add(int x)
{now+=(cnt[sum[x]]++);}
void modify(int i,int time)
{int tl=q[i].l,tr=q[i].r; if(tl<=c[time].x&&c[time].x<=tr){del(c[time].x);sum[c[time].x]=sum[c[time].x]^a[c[time].x]^a[c[time].x+1];add(c[time].x); swap(a[c[time].x],a[c[time].x+1]);}else{sum[c[time].x]=sum[c[time].x]^a[c[time].x]^a[c[time].x+1]; swap(a[c[time].x],a[c[time].x+1]);}
}
int main()
{int n,m;while(scanf("%d%d",&n,&m)!=EOF){cntq=0;cntc=0;now=0;memset(cnt,0,sizeof cnt);size=pow(n,2.0/3.0); for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum[i]=sum[i-1]^a[i];}for(int i=1;i<=m;i++){int op;scanf("%d",&op);if(op==1){int l,r;scanf("%d%d",&l,&r);q[++cntq].l=l-1;//注意是l-1q[cntq].r=r;q[cntq].id=cntq;q[cntq].t=cntc;}else{int x;scanf("%d",&x);c[++cntc].x=x;}}sort(q+1,q+cntq+1);int tl=1,tr=0,time=0;for(int i=1;i<=cntq;i++){int l=q[i].l,r=q[i].r,id=q[i].id,t=q[i].t;while(tl<l){del(tl++);}while(tl>l){add(--tl);}while(tr<r){add(++tr);}while(tr>r){del(tr--);}while(time<t){modify(i,++time);}while(time>t){modify(i,time--);}ans[q[i].id]=(ll)(r-l+1)*(r-l)/2-now;}for(int i=1;i<=cntq;i++){printf("%lld\n",ans[i]);}}
}