大体题意:
两个人,一个人认为一个数如果是素数的话,那么是符合要求的,另外一个人认为这个数的因子个数是素数的话,那么才是符合要求的!
给你一个区间 [L,R],求出该区间内 同时符合两个人要求 或者同时不符合两人要求数的个数!
思路:
很有意思的一道题目!
我们可以用间接法来求, 总数肯定是R-L + 1 可以求出符合一个但不符合另一个人数的个数 !
我们很容易想到 如果这个数是素数的话,那么他肯定是符合要求的!
接下来,问题就转换成了 求L到R区间内 有多少个数是合数并且这个数的因子个数是素数!
求这个问题,我们就要考虑这个数的素因子了!
假设这个数是p1^a * p2^b * p3 *c ......
如果素因子不止一个的话,那么他的因子个数是(a+1) * (b+1) * (c+1) 这肯定不是素数,首先就有三个因子!
因此素因子必须只有一个!
假设是p ^ n 我们只需要看看n 是不是素数即可! n肯定是很小的!
题目区间限制是10^12, 开方得 10^6 我们只需要枚举1 ~ 10^6内的素数即可!
注意这里的n 要大于1 ,否则他就是素数了!
注意 这是闭区间 ,wa了好几次!
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 1000000 + 10;
const int inf = 0x3f3f3f3f;
typedef long long ll;
vector<ll>prime;
int len_pri;
int vis[maxn];
void init(){
int len = sqrt(maxn) + 1;
for (int i = 2; i <= len; ++i)if (!vis[i])
for (int j = i*i; j <= maxn; j += i)vis[j] = 1;
for (int i = 2; i <= maxn; ++i)if (!vis[i])prime.push_back(i);
len_pri = (int)prime.size();
}
int main(){
init();
ll l,r;
scanf("%I64d %I64d",&l,&r);
ll ans = 0ll;
for (int i = 0; i < len_pri; ++i){
ll cur = 1ll;
if (prime[i] * prime[i] > r)break;
int sum = 0;
while(cur < l)cur *= prime[i],++sum;
while(cur <= r){
if (sum > 1 && !vis[sum+1])++ans;
cur *= prime[i];
++sum;
}
}
printf("%I64d\n",r-l+1ll-ans);
return 0;
}
2070. Interesting Numbers
Memory limit: 64 MB
Input
Output
Samples
input | output |
---|---|
3 7 | 4 |
2 2 | 1 |
77 1010 | 924 |
Problem Source: Ural Regional School Programming Contest 2015
My submissions All submissions (1468) All accepted submissions (409) Solutions rating (298)