求助,第二个点就没过(有注释)
查看原帖
求助,第二个点就没过(有注释)
708883
YIZHIXIAOLUREN1楼主2023/3/24 12:51
#include<bits/stdc++.h>
using namespace std;
#define N 6100000
int n,k;
int pre[N][30];
int f[N];
int q2[25];
int main(){
	q2[0]=1;
	for(int i=1;i<=23;i++)q2[i]=q2[i-1]*2;
	//预处理次方
   
	scanf("%d%d",&n,&k);
 	for(int i=1;i<=k;++i){
		int ss,tt;
		scanf("%d%d",&ss,&tt);
		if(tt<ss) tt+=n;
		pre[ss][0]=tt;
		if(tt<=n) pre[ss+n][0]=tt+n;
	}
	int mlen1=0,mlen2=0;
	
	for(int i=1;i<=2*n;i++){
		pre[i][0]=max(pre[i-1][0],pre[i][0]);
		if(pre[i][0]<i) pre[i][0]=0;
	} //用前缀和的思路预处理pre
	
	bool tr=0;
	for(int j=1;j<=2*n;j++){
		if(pre[j][0]-j+1>=n) tr=1;
	}//特判impossible
   
	for(int i=1;i<=20;i++){
		for(int j=1;j<=2*n;j++){
			if(pre[j][i-1]!=0){
				pre[j][i]=pre[pre[j][i-1]+1][i-1];//倍增预处理
				if(pre[j][i]-j+1>=n) tr=1;
           //特判impossible
			}
		}
	}
	if(!tr){
		puts("impossible");
		return 0;
	}
	
	int ans=0x3f3f3f3f;
	
	for(int s=1;s<=n;s++){
		int t=s+n-1,ns=s;
		int res=0;
		for(int i=19;i>=0;i--){
			if((pre[ns][i]<t)&&pre[ns][i]!=0){
				res+=q2[i];
				ns=pre[ns][i]+1;
           //逼近左端点
			}
			if(pre[ns][i]>=t&&i==0) res++;
        //特判
		}
		if(res!=0) ans=min(ans,res);
	}
	
	printf("%d\n",ans);
	
	return 0;
}
2023/3/24 12:51
加载中...