前言
爆零警告
JZOJ 3187 洛谷 3076 的士
分析
玄学贪心,就不放代码了
JZOJ 3188 找数
题目
找出第N个最小素因子是P的正整数
分析
首先在 p > = 1000 p>=1000 p>=1000时暴力即可,在之前可以深搜+容斥解决,二分答案
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int inf=1000000000,N=1000000;
int n,p,v[N+1],prime[N+1],cnt; long long ans;
inline void dfs(int dep,int tot,long long mul,long long mid){
if (dep>cnt){
if (!tot) return;
if (tot&1) ans-=mid/mul;
else ans+=mid/mul;
return;
}
if (1ll*mul*prime[dep]<=mid) dfs(dep+1,tot+1,mul*prime[dep],mid);
dfs(dep+1,tot,mul,mid);
}
signed main(){
scanf("%d%d",&n,&p);
for (rr int i=2;i<=N;++i){
if (!v[i]) v[i]=prime[++cnt]=i;
for (rr int j=1;j<=cnt&&prime[j]*i<=N;++j){
v[i*prime[j]]=prime[j];
if (i%prime[j]==0) break;
}
}
if (p>=1000){
rr int sum=1;
for (ans=p;ans*p<=inf;ans+=2)
if (v[ans]>=p){
if ((++sum)==n) return !printf("%d",ans*p);
}
return !putchar(48);
}
while (prime[cnt]>=p) --cnt;
rr int l=1,r=inf/p+1;
while (l<r){
rr int mid=(l+r)>>1; ans=mid;
dfs(1,0,1,mid);
if (ans>=n) r=mid;
else l=mid+1;
}
return !printf("%d\n",l*p>inf?0:l*p);
}
JZOJ 3189 解密
题目
Mirko要解一段加密文,但他只知道某一个句子是原文的一部分。你的任务是要在密文中找到第一个对应这个句子的地方。
文段是通过用某个单词(可能和原文一样的单词)替换原始文段每一个单词来加密的。如果某些单词在原文出现一次以上,就会使用相同的替换单词来替换。没有两个不同的单词使用相同的替换单词。单词是通过空格隔开的小写字母序列。句子是连续单词的序列。
分析
这道题很巧,首先处理与它最近的相同字符串的距离,没有为0,然后KMP求解,注意当距离为0时,需要特判