POJ 3292 : Semi-prime H-numbers

概要

H={4N+1|Nは0以上の整数}とする.この時,Hの元xが1とxの組以外の積で表現できないものをHの素数と呼ぶことにする.h \in Hが与えられたとき,2つのHの素数の積で表すことができるh以下の数の個数を計算する.

解法

素数の列挙は篩を使っていい.
あとは,事前に数え上げる処理を行っておけばいい.

Hの素数の積は1通りでしか表せないと勘違いしていたので,なかなか通らなかった.
実際はそんなことはなく,9 * 111089 = 33 * 30297がその反例.

PKU 3292 Semi-prime H-numbers - 敗戦記 を見た.

int n;
ll prime[100000];
bool isnPrime[1000010];
int dp[1000010];
int h;
int main(){
    n = 0;
    for(int i = 5; i <= 1000001; i += 4) if(!isnPrime[i]){
        prime[n] = i;
        ++n;
        for(int j = i * 5; j <= 1000001; j += i * 4)
            isnPrime[j] = true;
    }
    for(int i = 0; i < n; ++i)for(int j = i; j < n && prime[i] * prime[j] <= 1000010; ++j){
        dp[prime[i] * prime[j]] = 1;
    }
    for(int i = 1; i <= 1000001; ++i){
        dp[i] += dp[i-1];
    }
    for(;;){
        scanf("%d", &h);
        if(h == 0) return 0;
        printf("%d %d\n", h, dp[h]);
    }
}