用vector维护每种颜色出现位置,二分左右端点,右端点用upperbound,交换直接把vector里的也交换
#include<bits/stdc++.h> #define pb push_back using namespace std; const int maxn=300009; int n,m; struct node{ int col,w; }a[maxn]; vector<int>c[maxn];//颜色x出现位置 int main(){ scanf("%d%d",&n,&m); for(int i=1,x;i<=n;i++){ scanf("%d",&x); c[x].pb(i); a[i].col=x,a[i].w=c[x].size()-1; } for(int i=1,op,x,y,z;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&x,&y,&z); if(c[z].size()==0){ printf("0 ");continue; } int pos1=lower_bound(c[z].begin(),c[z].end(),x)-c[z].begin(); int pos2=upper_bound(c[z].begin(),c[z].end(),y)-c[z].begin();//查右端点用upper printf("%d ",pos2-pos1); } else{ scanf("%d",&x); if(a[x].col==a[x+1].col)continue; c[a[x].col][a[x].w]=x+1; c[a[x+1].col][a[x+1].w]=x; swap(a[x],a[x+1]); } } }