还没学莫队,感觉纯分块也能做,但只有40分。
#include<bits/stdc++.h>
#define fo(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
typedef long long ll;
using namespace std;
inline ll qr()
{
char ch=getchar();ll x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
#define qr qr()
const int Ratio=0;
const int N=2000005;
const int maxi=INT_MAX;
ll n,m,cnt;
ll a[N],sv[N],st[N],ed[N],pre[N],las[N],bl[N];
void mdf(ll p,ll v)
{
ll cox=a[p],no=las[cox];
a[p]=v;
if(no==p)
las[cox]=pre[p];
else if(no>p)
{
while(pre[no]!=p)
no=pre[no];
pre[no]=pre[p];
fo(i,st[bl[no]],ed[bl[no]])
sv[i]=pre[i];
sort(sv+st[bl[no]],sv+ed[bl[no]]+1);
}
no=las[v];
if(no<p)
{
las[v]=p;
pre[p]=no;
fo(i,st[bl[p]],ed[bl[p]])
sv[i]=pre[i];
sort(sv+st[bl[p]],sv+ed[bl[p]]+1);
}
else
{
while(pre[no]>p)
no=pre[no];
pre[p]=pre[no];
pre[no]=p;
fo(i,st[bl[p]],ed[bl[p]])
sv[i]=pre[i];
sort(sv+st[bl[p]],sv+ed[bl[p]]+1);
fo(i,st[bl[no]],ed[bl[p]])
sv[i]=pre[i];
sort(sv+st[bl[no]],sv+ed[bl[no]]+1);
}
}
ll Acheron(ll l,ll r)
{
ll ans=0;
if(bl[l]==bl[r])
{
fo(i,l,r)
if(pre[i]<l)
ans++;
return ans;
}
else
{
fo(i,l,ed[bl[l]])
if(pre[i]<l)
ans++;
fo(i,st[bl[r]],r)
if(pre[i]<l)
ans++;
fo(i,bl[l]+1,bl[r]-1)
{
ll ls=st[i],rs=ed[i],re=0,mid;
while(ls<=rs)
{
mid=(ls+rs)>>1;
if(sv[mid]<l)
ls=mid+1,re=mid-st[i]+1;
else
rs=mid-1;
}
ans+=re;
}
return ans;
}
}
signed main()
{
n=qr,m=qr;ll sq=sqrt(n);
fo(i,1,n)
{
a[i]=qr;
pre[i]=las[a[i]];
las[a[i]]=i;
}
fo(i,1,sq)
st[i]=n/sq*(i-1)+1,ed[i]=n/sq*i;
ed[sq]=n;
fo(i,1,sq)
fo(j,st[i],ed[i])
bl[j]=i;
fo(i,1,n)
sv[i]=pre[i];
fo(i,1,sq)
sort(sv+st[i],sv+ed[i]+1);
while(m--)
{
string s;
cin>>s;
ll a=qr,b=qr;
if(s=="R")
mdf(a,b);
else
printf("%lld\n",Acheron(a,b));
}
return Ratio;
}