题目要用权值线段树来解决没有问题,但是权值线段树还要维护所出现的区间,采用主席树,每一种颜色建一棵树,记录其所在的位置,由于建树过程中需要动态开点,更新操作时不需要动态开点,所以要特判一下是否要开点
const int N=3e5+5;
int n,m;
int i,j,k;
int a[N];
struct Node
{
int l,r;
int sum;
#define lson id<<1
#define rson id<<1|1
}t[N*40];
vector<int> v;
int root[N],tot;
void update(int l,int r,int &now,int pos,int c)
{
if(!now) now=++tot;
t[now].sum+=c;
if(l==r) return ;
else {
int mid=l+r>>1;
if(mid>=pos) update(l,mid,t[now].l,pos,c);
else update(mid+1,r,t[now].r,pos,c);
}
}
int query(int L,int R,int l,int r,int now)
{
if(L>=l && r>=R) return t[now].sum;
else{
int mid=L+R>>1;
int ans=0;
if(mid>=l) ans+=query(L,mid,l,r,t[now].l);
if(r>=mid+1) ans+=query(mid+1,R,l,r,t[now].r);
return ans;
}
}
signed main()
{
//IOS;
while(~sdd(n,m)){
for(int i=1;i<=n;i++){ sd(a[i]); update(1,n,root[a[i]],i,1); }
for(int i=1;i<=m;i++){
int x,y,opt,c,ans;
sdd(opt,x);
if(opt==1){
sdd(y,c);
ans=query(1,n,x,y,root[c]);
pd(ans);
} else{
update(1,n,root[a[x]],x,-1);
update(1,n,root[a[x]],x+1,1);
update(1,n,root[a[x+1]],x+1,-1);
update(1,n,root[a[x+1]],x,1);
swap(a[x],a[x+1]);
}
}
}
//PAUSE;
return 0;
}