| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
素数筛+结果打表#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define lowbit(x) ((x) & (-x))
using namespace std;
/*
定义:
H-Number = 4n+1, n=0,1,2,...
H-Primes = p*q,其中p和q分别是H-Number中的素数。
问题:求1~h的所有符合条件的H-Primes的个数,h<=1000,001。
思路:
素数筛 + 结果打表(树状数组求1~n的和),注意当一个问题
的所有测试用例都能在一次性求出时,则一次性求出。
*/
vector<int> primes;
const int maxn = 1000001;
bool isPrime[maxn + 10];
bool visited[maxn + 10];
int c[maxn]; // 树状数组适合求动态更新的前i项和
int getSum(int x){
// 获取前x的sum和
int sum = 0;
for (int i = x; i >= 1; i -= lowbit(i))
sum += c[i];
return sum;
}
void update(int v, int x){
for (int i = v; i <= maxn; i += lowbit(i))
c[i] += x;
}
void findPrimes(){
for (int i = 5; i <= maxn; i += 4){
if (isPrime[i]){
for (int j = i + i; j <= maxn; j += i)
isPrime[j] = false;
primes.push_back(i);
for (int j = 0; j < primes.size(); j++){
if (maxn / i >= primes[j]){
if (!visited[i * primes[j]]){
visited[i * primes[j]] = true;
update(i * primes[j], 1); // 树状数组更新
}
}else{
break;
}
}
}
}
}
int main(){
int n;
primes.clear();
memset(isPrime, true, sizeof(isPrime));
memset(visited, false, sizeof(visited));
memset(c, 0, sizeof(c));
findPrimes(); // 求出所有的H-semi-number个数
while (~scanf("%d", &n) && n){
printf("%d %d\n", n, getSum(n));
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator