みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

わぁいBIT あかりBIT大好き

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

わぁいBIT あかりBIT大好き

投稿記事 by みけCAT » 13年前

AOJ 0162 Hamming Numbers
この問題についてです。
某本(蟻本ではない)には、2または3または5を掛けていき、
ハミング数を列挙して数えるというアルゴリズムが載っていましたが、
なんか複雑そうだと思いました。

掛ける数が2、3、5と全て素数なので、掛ける個数を変えれば全て違う値になることを考えると、
最初に列挙して累積和をとっておけばいいことがわかります。
累積和…「ペロッ、これはBIT!」
という訳で書きました。

CODE:

#include 

#define NUM_MAX 1000000

int table[NUM_MAX];

void bit_add(int n,int pos) {
	while(pos0) {
		result+=table[pos-1];
		pos-=(pos & (-pos));
	}
	return result;
}

void get_hamming_num(void) {
	int now,now2,now3;
	for(now=1;now

#define NUM_MAX 1000000

int hamming_num[NUM_MAX];

void make_hamming_num(void) {
	int i;
	int now,now2,now3;
	for(now=1;now<=NUM_MAX;now*=2) {
		for(now2=now;now2<=NUM_MAX;now2*=3) {
			for(now3=now2;now3<=NUM_MAX;now3*=5) {
				hamming_num[now3-1]=1;
			}
		}
	}
	for(i=1;i<NUM_MAX;i++) {
		hamming_num[i]+=hamming_num[i-1];
	}
}

int main(void) {
	int start,end;
	make_hamming_num();
	while(1) {
		scanf("%d",&start);
		if(start==0)break;
		scanf("%d",&end);
		printf("%d\n",hamming_num[end-1]-hamming_num[(start-1)-1]);
	}
	return 0;
}
前処理O(M)、クエリ処理O(N)
こっちももちろんAccepted
なんでBITのやつが通っちゃったんだろう?テストケース仕事しろ。[/spoil]

コメントはまだありません。