求条0pts AC on hack(悬关)
查看原帖
求条0pts AC on hack(悬关)
1117384
CharlesWY楼主2025/6/5 12:03

样例过了,但只过了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;
}
2025/6/5 12:03
加载中...