样例过了,但只过了hack,代码有简单注释,求条非常感谢qwq。
#include <iostream>
#define int long long
using namespace std;
const int N=15010;
int T,n,a[N],m,l,r,f[N][30],t[15];
signed main(){
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
}
for(int i=1;i<=13;++i){
t[i]=n+1;
}
for(int i=n;i>=1;--i){
f[i][0]=t[a[i]];//求倍增数组初始化
t[a[i]]=i;
}
// for(int i=1;i<=n;++i){
// cout<<f[i][0]<<" ";
// }
for(int i=0;i<=20;++i) f[n+1][i]=f[n+2][i]=n+1;//防止越界
for(int j=1;j<=20;++j){
for(int i=1;i<=n;++i){
f[i][j]=f[f[i][j-1]][j-1];//求倍增数组
}
}
// for(int i=1;i<=n;++i){
// for(int j=0;j<=20;++j){
// cout<<f[i][j]<<" ";
// }
// cout<<"\n";
// }
scanf("%lld",&m);
while(m--){
int tampans=0;
scanf("%lld%lld",&l,&r);
int kp=l,lst=l;
while(kp<=r){
for(int i=20;i>=0;--i){
if(f[kp][i]<=r){
kp=f[kp][i]+1;//往后跳
}
}
if(kp>r) break;//如果跳完了就结束
while(kp<=r&&f[kp][0]>r){
tampans++;//找下一个能跳的数
kp++;
}
// cout<<kp<<" ";
}
printf("%lld\n",tampans);//输出
}
}
return 0;
}