正解:二分
解题报告:
话说其实我开始看到这题想到的是分块,,,
但是显然不用这么复杂,,,因为仔细看下这题,会发现每次只改变相邻的兔子的位置
所以开个vector(或者开个数组也成QwQ(数组就能用lower_bound
按顺序存下来每个颜色的兔子的位置,每次修改只用O(1)地改就好了
然后复杂度是O(nlogn),和莫队复杂度一样却简单很多
over
(对了,这题我本来想的是分块嘛,我就搜了下可不可以用分块,只看到了一篇题解,说分块会被时空双卡,但是可以优化,我还没有仔细看先贴个链接QAQ
然后放下二分代码QAQ
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define rp(i,x,y) for(register ll i=x;i<=y;++i)
const ll N=300000+2;
ll n,m,a[N];
vector<ll>gg[N];
inline ll read()
{
register char ch=getchar();register ll x=0;register bool y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=getchar();
if(ch=='-')ch=getchar(),y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
return y?x:-x;
}
inline void wk1(){ll l=read(),r=read(),c=read();if(gg[c].size()==0){printf("0\n");return;}printf("%d\n",upper_bound(gg[c].begin(),gg[c].end(),r)-lower_bound(gg[c].begin(),gg[c].end(),l));}
inline void wk2(){ll x=read();if(a[x]==a[x+1])return;gg[a[x]][lower_bound(gg[a[x]].begin(),gg[a[x]].end(),x)-gg[a[x]].begin()]=x+1;gg[a[x+1]][lower_bound(gg[a[x+1]].begin(),gg[a[x+1]].end(),x+1)-gg[a[x+1]].begin()]=x;swap(a[x],a[x+1]);}
int main()
{
n=read();m=read();rp(i,1,n)a[i]=read(),gg[a[i]].push_back(i);
while(m--){ll op=read();op==1?wk1():wk2();}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define rp(i,x,y) for(register ll i=x;i<=y;++i)
const ll N=300000;
ll n,m,a[N];
vector<ll>gg[N];
inline ll read()
{
register char ch=getchar();register ll x=0;register bool y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=getchar();
if(ch=='-')ch=getchar(),y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
return y?x:-x;
}
inline ll lb(ll y,ll x)
{
ll l=0,r=gg[x].size()-1;
while(l<=r){ll mid=(l+r)>>1;if(gg[x][mid]>=y)r=mid-1;if(gg[x][mid]<y)l=mid+1;}
return l;
}
inline ll ub(ll y,ll x)
{
ll l=0,r=gg[x].size()-1;
while(l<=r){ll mid=(l+r)>>1;if(gg[x][mid]>y)r=mid-1;if(gg[x][mid]<=y)l=mid+1;}
return l;
}
inline void wk1(){ll l=read(),r=read(),c=read();if(gg[c].size()==0){printf("0\n");return;}printf("%d\n",ub(r,c)-lb(l,c));}
inline void wk2(){ll x=read();if(a[x]==a[x+1])return;gg[a[x]][lb(x,a[x])]=x+1;gg[a[x+1]][lb(x+1,a[x+1])]=x;swap(a[x],a[x+1]);}
int main()
{
n=read();m=read();rp(i,1,n)a[i]=read(),gg[a[i]].push_back(i);
while(m--){ll op=read();op==1?wk1():wk2();}
return 0;
}