CF237C
我来水题解啦!!
首先这题和素数有关,我们就先需要一个线性筛:
int prm[1000005],tot;
bool vis[1000005];
void init(){
vis[1]=vis[0]=1;
for(int i=2;i<=b;i++){
if(!vis[i])prm[++tot]=i;
for(int j=1;j<=tot;j++){
if(i*prm[j]>b)break;
vis[i*prm[j]]=1;
if(i%prm[j]==0)break;
}
}
}
然后让我们分析一下这题的答案:
设最优解为 \(ans\) ,其他答案为 \(sol\) ,若 \(sol<ans\) ,则这个 \(sol\) 一定无法满足条件;若 \(sol>ans\) ,则 \(sol\) 可以满足条件,但是不是最优的。
那么显然,对于这种答案分布,我们可以利用二分法求解。这是一个二分答案的板子:
int l=1,r=b-a+1;
while(l<r){
int mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
cout<<r<<endl;
接下来我们考虑check
函数:
其实很简单,我们只需要用 \(l\) 和 \(r\) 模拟一个区间,再利用一个 \(num\) 表示区间内素数的个数,如果在某一时刻 \(num<k\) ,则此答案无法满足要求,否则可以,代码:
bool check(int len){
int t=a,h=a-1,num=0;
while(h-t+1<len){
h++;
if(!vis[h])num++;
}
while(h<=b){
if(num<k)return 0;
h++;if(!vis[h])num++;
t++;if(!vis[t-1])num--;
//模拟区间向前移动一个位置
}
return 1;
}
最后对于无解的判断:如果整个区间内的素数个数都不到 \(k\) ,换句话说,就算是把整个区间覆盖住也无法满足需求,那么就是无解,特判代码:
int num=0;
for(int i=a;i<=b;i++)if(!vis[i])num++;
if(num<k){cout<<-1<<endl;return 0;}
那么这题就愉快地结束了!好水啊
此题虽然 \(a,b,k\) 范围都是百万,但是 \(n\log n\) 做法完全可过。
\[\mathfrak{End.}
\]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类