题解 SP9385【MAIN111 - Strictly not a Prime】
posted on 2021-06-21 20:30:31 | under 题解 | source
这道题,有两个比较恶心的点:
- 「between two given integers A and B」,说的是 \(A\) 和 \(B\) 之间,并没有保证 \(A<B\);
- 「subsequence」指的是子序列(不连续),不是子段(连续)。
首先,我们先想想怎么判断一个数是否是「Strictly not a Prime」,不难想到一种暴力方法:
把数字 a 转换成字符串 s
遍历 i 为 s 的所有子序列:
如果 i 是质数:
返回 a 不是 Strictly not a Prime
返回 a 是 Strictly not a prime
判断 \(i\) 是不是质数很简单,写个线性筛 \(O(n=10^5)\) 筛一下,再 \(O(1)\) 判一下。
那怎么遍历 \(s\) 的所有子序列呢?我们可以写个 dfs,搜选或不选两种状态,搜到尽头,结果就是 \(s\) 的所有子序列。
接着,我们看到 \(1\leq T\leq 10^5\) 这个惊人的数据范围,显然不能每次都重新统计一次。考虑设 \(f_i\) 表示 \(i\) 是不是「Strictly not a Prime」,那么题目的询问实际上就是求 \(\sum^{b}_{i=a} f_i\)。
Q:那怎么快速求 \(\sum^{b}_{i=a} f_i\) 呢?
A:使用前缀和。记 \(s_x=\sum^{x}_{i=1} f_i\),那么 \(\sum^{b}_{i=a} f_i=s_b-s_{a-1}\)。
至此,本题得解。时间复杂度好像很离谱?其实很低,设 \(n=10^5\),一共也就是线性筛的 \(O(n)\),加上算 \(f_i\) 的 \(O(n\times 2^{\log_{10}{10^5}})\),再加前缀和的 \(O(n)\),最后是回答询问的 \(O(T)\),一共就是 \(O(n+T)\),非常合理。
下面给出代码:
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
template<int N> class LineSiever{
private:
bool isp[N+10];
int n,p[N+10];
public:
LineSiever():n(0){
for(int i=1;i<=N;i++) isp[i]=1;
isp[0]=isp[1]=0;
for(int i=2;i<=N;i++){
if(isp[i]) p[++n]=i;
for(int j=1;j<=n&&1LL*i*p[j]<=N;j++){
if(isp[i*p[j]]=0,i%p[j]==0) break;
}
}
}
operator int(){return n;}
bool operator()(int x){return isp[x];}
int operator[](int x){return p[x];}
};
LineSiever<100010> p;
stringstream ss;
string chg(int a){
string r;
ss.clear(),ss<<a,ss>>r;
return r;
}
int chg(string a){
int r;
ss.clear(),ss<<a,ss>>r;
return r;
}
int n;
string dig;
bool dfs(int i,int tot){
if(i==n) return p(tot);
return dfs(i+1,tot*10-48+dig[i])||dfs(i+1,tot);
}
bool check(int a){
dig=chg(a);
n=dig.size();
return !dfs(0,0);
}
int ans[100010];
int t,a,b;
int main(){
for(int i=1;i<=1e5;i++) ans[i]=ans[i-1]+check(i);
//for(int i=1;i<=1e5;i++) if(check(i)) cout<<i<<endl;
cin>>t;
while(t--){
cin>>a>>b;
if(a>b) swap(a,b);
cout<<ans[b]-ans[a-1]<<endl;
}
return 0;
}
附一组易错样例:
input:
1
1 100000
output:
2568
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/solution-SP9385.html