ãã¶ãä»æ¥ã使ããªãã¨æããã§ããã©ï¼åæ¨çï¼ï¼
ã¿ã¤ãã«ã®å ãã¿ã¯ ããï¼
ä¸ã®ã¹ã©ã¤ãã§ã¯ï¼ã¯ã¼ããµã¤ãº \(w\) ã«å¯¾ãã¦ï¼ä»¥ä¸ã®æ¼ç®ã \(O(\log w)\) time ã§æ±ããæ¹æ³ãæ¸ããã¦ãã¾ãï¼
- ç«ã£ã¦ããæä¸ä½ã®ããããåãåºãï¼
msb
- ç«ã£ã¦ãããããã®åæ°ãåãåºãï¼
popcount
ãã®è¨äºã§ã¯ï¼ãã®ãã¡ msb
ã®æ·»åã \(O(1)\) time ã§æ±ããæ¹æ³ãç´¹ä»ãã¦ã¿ã¾ãï¼
ä»å¾ï¼åã« msb
ã¨è¨ã£ãå ´åã«æ·»åã®æ¹ãæããã¨ã«ãã¾ãï¼
ã½ã¼ã¹ã³ã¼ãã¯ä¸çªä¸ã«ããã¾ãï¼
åèã«ããè³æã¯ãã¤ãã® CS166 ã® ã¹ã©ã¤ãï¼
以ä¸ã§ã¯ï¼ã¯ã¼ããµã¤ãºã®ååæ¼ç®ããã³ãããæ¼ç®ãä¸åä½æéã§è¨ç®ã§ãããã¨ãä»®å®ãã¾ã*1ï¼ããªãã¡ï¼\(w\) bits ã®æ´æ°ã«é¢ãããããã®æ¼ç®ãä¸åä½æéã§è¡ãã¾ãï¼
ã¾ãï¼æ±ãæ´æ°ã¯ç¬¦å·ãªãæ´æ°ã¨ãï¼\(2^w\) ãæ³ã¨ãã¦èãã¾ãï¼ãªã¼ãã¼ããã¼ã¯ãããªã«ããã¨ãããã¨ï¼ï¼
åºæ¬æ¹é
ã¾ãï¼\(w\) bits ã®æ´æ°ã \(\sqrt{w}\) åã® \(\sqrt{w}\) bits ã®æ´æ°ãã¡ã ã¨è¦ãªãã¦ã¿ã¾ãï¼ãã®åã ã®å°ããæ´æ°ã®ãã¨ãæãã¦ãããã¯ã¨å¼ãã ããããã¨ã«ãã¾ãï¼
ãããããã¨ã«ããï¼\(\sqrt{w}\) åã®æ´æ°ãï¼ä¸åä½æéã§ï¼ä¸¦åå¦çãããã¨ãã§ãã¾ãï¼
ãã®ä¸¦åå¦çã«ãã£ã¦å®æ°æéã§ã§ããæ¼ç®ãããã¤ãç´¹ä»ãï¼ããããçµã¿åããããã¨ã§ msb
ãæ±ãã¾ãï¼
è£å©ã®æ¼ç®ãã¡
以ä¸ã§ã¯ï¼èª¬æã®ããã« \(w = 16\) ã¨ãã¦ã¿ã¾ããï¼å¹³æ¹æ°ãªããªãã§ãé©ç¨ã§ããã¯ãã§ãï¼å¹³æ¹æ°ãããªãå ´åã¯é©å½ãªå®æ°ååè¡ãã¨ï¼ã¯ã¼ããµã¤ãºãã大ããæå°ã®å¹³æ¹æ°ãã¨ãã¥ã¬ã¼ãããæ°æã¡ã§ï¼ããæãã«ãªãã¨æãã¾ãï¼
log2p1
\(\sqrt{w}\) bits ã®æ´æ° \(x\) ã«å¯¾ãã¦ï¼\(\lfloor\log_2 x\rfloor+1\) ãæ±ãã¾ãï¼ããã¯ï¼\(x\) ã®ç«ã£ã¦ããæä¸ä½ãããã®ï¼ä¸ä½ããããã 1-indexed ã§ã®ï¼æ·»åã«å¯¾å¿ãã¾ãï¼
ããªãã¡ï¼msb(x)
㯠log2p1(x) - 1
ã«ç¸å½ãã¾ãï¼ãã ã 0
ã«ã¤ãã¦ã¯é©å½ã«ã©ãã«ããããããªãã£ãããã¾ãï¼ï¼
æä¸ä½ããããç«ã£ã¦ããã \(\sqrt{w}\) ãè¿ãã¦ãã¾ãã¾ãï¼
æ´æ° 0010
ã® log2p1
ãæ±ããã®ãä¾ã¨ãã¦æããªããæé ãæ¸ãã¦ããã¾ãï¼çãã \(2\) ã«ãªã£ã¦ãããã¨ããããã§ãï¼
ã¾ãï¼äºãã«ç°ãªãä½ç½®ã« 1
ãé
ç½®ããæ´æ°ã \(\sqrt{w}\) å並ã¹ãæ´æ°ãç¨æãã¾ãï¼
1000 0100 0010 0001
ãããã®åè¦ç´ ã§ãã \(y_i = 2^i\) 㨠\(x\) ãæ¯è¼ãï¼\(x \ge y_i\) ã§ãã \(i\) ã®åæ°ã§ãããã¨ããããã¾ãï¼
\(x \ge y_i \iff x-y_i \ge 0\) ã§ããã¾ãããï¼å¼ãç®ããã¦ã¿ã¾ãããï¼
0010 0010 0010 0010 -) 1000 0100 0010 0001 ---------------------- 1001 1110 0000 0001
\(x-y_i \ge 0\) ãæãç«ã¤ã¨ããã®ã¯ï¼2 ã®è£æ°è¡¨ç¾ãèãããªã©ãã¦ï¼æä¸ä½ããããç«ããªããã¨ã«ç¸å½ãã¾ãï¼ããã§ããæä¸ä½ãããã¨ããã®ã¯åãããã¯ãã¨ã®æä¸ä½ããããæãã¦ãã¾ãï¼
æä¸ä½ããããç«ã£ã¦ããæ´æ°ããã£ãã¨ãï¼ãã£ãªã¼ï¼ããã¼ï¼ï¼ãçºçãã¦ï¼ããããä¸å´ã®ãããã¯ã«ãå½±é¿ãåºã¾ããï¼å
·ä½çã«ã¯ï¼ãã®ãããã¯ã®ã¿ãåãåºãã¦å¼ãç®ããã¨ããããçµæã 1
å°ãããªã£ã¦ãã¾ãã¾ãï¼
ãªãã§ããï¼å¤§ããæ°ãä¸ä½å´ã«ä¸¦ã¹ã¦ãããã¨ã«ããï¼å¼ããããã¶ãã«ã¯åé¡ãªãã¯ãã§ãï¼1
æ¸ããã¨ã§æä¸ä½ããããå¤ããã®ã¯ï¼ç¬ç«ã«è¨ç®ããå ´åã®ï¼çµæã 0000
ã«ãªãã¨ãã§ããï¼ä»ã®æ¡ã§æä¸ä½ãããã 1
ã«ãªã£ã¦ãããã¨ããï¼ãããªããã¨ã¯ãªããã*2ï¼
éã«ï¼å°ããæ°ãä¸ä½å´ã«ä¸¦ã¹ã¦ããã¨ä»¥ä¸ã®ããã«ãªãï¼æä¸ä½ãããã®çµæãç°ãªã£ã¦ãã¾ãã¾ãï¼
0010 0010 0010 0010 -) 0001 0010 0100 1000 ---------------------- 0000 1111 1101 1010
ã§ï¼çµå±ï¼ããã§ã¯ãªãã¦ï¼ãã£ãã®é åºã§å¼ãç®ããã¦ï¼æ¬¡ã®ãã®ãå¾ããã¾ããï¼
1001 1110 0000 0001
ã»ããã®ã¯ç«ã£ã¦ããªãæ¹ãªã®ã§ï¼å転ããã¦ããã¾ãï¼
~) 1001 1110 0000 0001 ---------------------- 0110 0001 1111 1110
ããã§ï¼æä¸ä½ãããã®ã¿ãåãåºãã®ã¯ç°¡åã§ãï¼
0110 0001 1111 1110 &) 1000 1000 1000 1000 ----------------------- 0000 0000 1000 1000
ãã¦ï¼ãã¨ã¯ãã® 1
ã®åæ°ãæ°ããã°ããã§ãï¼
ä½ãæ¹ããï¼åãããã¯ã«ãã 1
㯠\(0\) åã \(1\) åãªã®ã§ï¼åãããã¯ã®å¤èªä½ã 1
ã¾ã㯠0
ã«ãã¦ãã¾ãï¼ãããã¯å
¨ä½ã®åè¨ãæ±ãã¦ãããã¨ãããã¨ã«ãªãã¾ãï¼
0000 0000 1000 1000 >>) 3 // 4-1 ----------------------- 0000 0000 0001 0001
ãããå ¥åã¨ãã次ã®ãµãã«ã¼ãã³ãèãã¾ãããï¼
popcount
å¤ã 0
ã¾ã㯠1
ã§ããããã㯠\(\sqrt{w}\) åã並ã¹ãæ´æ° \(x\) ãåãåãï¼ãã® 1
ã®åæ°ãè¿ãã¾ãï¼
æç´ã«ã¯ï¼æ¬¡ã®ããã«ã·ãããè¡ãï¼è¶³ãã¨ããããã§ãï¼
0000 0000 0001 0001 (x << 0) 0000 0000 0001 0001 (x << 4) 0000 0000 0001 0001 (x << 8) +) 0000 0000 0001 0001 (x << 12) ------------------------------------- XXXX XXXX XXXX 0010 0010 0010 0001
XXXX
ã¯ãªã¼ãã¼ããã¼ã§ç¡è¦ãããé¨åã§ãï¼
ã¨ããã§ï¼ããã¯ä¹ç®ã§ããï¼ã·ããå¹
ãæããæ°ã§ç«ã£ã¦ãããããã«å¯¾å¿ãã¾ãï¼ããªãã¡ï¼0
, 4
, 8
, 12
bit ç®ãç«ã£ã¦ããæ´æ°ãæããã¨ããã§ãï¼
0000 0000 0001 0001 *) 0001 0001 0001 0001 ---------------------- 0010 0010 0010 0001
åãã«ãªã£ã¦ãã¾ããï¼é©å®èªåã§è¨ç®ãã¦ãï¼ï¼
èå³ãããã®ã¯ä¸çªä¸ã®ãããã¯ã®ã¿ã§ãã®ã§ï¼ãã¹ã¯ããã¶ãã¾ãï¼
0010 0010 0010 0001 &) 1111 0000 0000 0000 ---------------------- 0010 0000 0000 0000
ãã¨ã¯ã·ãããã¦ï¼çããå¾ã¾ãï¼
0010 0000 0000 0000 >>) 12 ----------------------- 0000 0000 0000 0010
æ³å®éãï¼\(2\) ãå¾ããã¾ããï¼ããããï¼
summary
æºå段éã®æå¾ã§ãï¼ããè¤éãªã®ã§ããï¼ããã¯æ¬¡ã®ãããªæ¼ç®ã§ãï¼
\(w\) bits ã®æ´æ°ãå ¥åã¨ãã¦åãåãï¼åºå㯠\(\sqrt{w}\) bits ã®æ´æ°ã§ãï¼
å
¥å \(x\) ã \(\sqrt{w}\) bits ãã¨ã«åºåãã¾ãï¼ããã® \(i\) ãããã¯ç®ã 0
ã§ããã¨ãåºå \(y\) ã® \(i\) bit ç®ã¯ 0
ï¼ããã§ãªãã¨ã 1
ã§ãï¼
ãã¨ãã°ï¼æ¬¡ã®ãããªæãã§ãï¼
summary(0000 0010 1011 0000) = 0110
ã¾ãï¼ãããã¯ã®æä¸ä½ãããã¨ãã以å¤ã«åãã¾ãï¼
0000 0010 1011 0000 &) 1000 1000 1000 1000 ---------------------- 0000 0000 1000 0000
0000 0010 1011 0000 &) 0111 0111 0111 0111 ---------------------- 0000 0010 0011 0000
ãæä¸ä½ãããã®ã¿ãç«ã£ã¦ãããã®ãã¨ãæä¸ä½ãããã¯å¸¸ã«ç«ã£ã¦ããªããã®ãã«ã¤ãã¦åãã¦èãã¾ãï¼
åå ´åã«ã¤ã㦠summary
ãæ±ãï¼ãããã® or
ãæ±ããã¨ãããã¨ããããã¾ããï¼
æä¸ä½ãããã®ã¿ãç«ã¡ãããã®
å ã»ã©ã®ããã«ã·ããããã¨ããã§ãï¼
ã·ããã®çµæï¼æ¬¡ã®ããã«ãªã£ã¦ãããã¨ããããã§ãï¼
a000 b000 c000 d000 *) ???? ???? ???? ???? ---------------------- abcd ???? ???? ????
ãã¨ãã°æ¬¡ã®ããã«ããã¨ããã§ãï¼
000d 0000 0000 0000 (x << 9) 00c0 00d0 0000 0000 (x << 6) 0b00 0c00 0d00 0000 (x << 3) a000 b000 c000 d000 (x << 0)
åæ¡ã«ã¤ãã¦ï¼ç½®ããããããã¯é«ã ã²ã¨ã¤ãªã®ã§ï¼ç¹°ãä¸ãããªã©ãçºçãããã¨ã¯ããã¾ãããï¼
a000 b000 c000 d000 *) 0000 0010 0100 1001 ---------------------- abcd bcd0 cd00 d000
ãã¨ã¯ï¼ã·ãããã¦ä¸ä½ããããæ¶ãã¡ããã¾ãããï¼
abcd bcd0 cd00 d000 >>) 12 ----------------------- 0000 0000 0000 abcd
æä¸ä½ãããã¯ç«ã£ã¦ããªããã®
次ã®ããã«ãªã£ã¦ãã¾ããï¼
0??? 0??? 0??? 0???
ã¨ããããï¼æä¸ä½ãããã®ã¿ãç«ã¡ãããã¿ã¼ã³ã«å¸°çãããããã¨æ¥½ãããªã®ã§ï¼ããããæ¹éã§èãã¦ã¿ã¾ãï¼
0000
ã®å ´åã«æä¸ä½ãããã 0
ï¼ãã以å¤ã®å ´åã« 1
ã«ãªã£ã¦ã»ããã§ããï¼
ããï¼1000
ããå¼ãã¨ãã®éã«ãªãã®ã§ï¼ã¨ãããããããæ±ãã¦ãããããå転ããã¦ã¿ã¾ãããï¼0000
ããå¼ãã¨ç¹°ãä¸ãããèããã®ã大å¤ããã§ãï¼
å ã»ã©ã®ä¾ã§ã¯ï¼æ¬¡ã®ããã«ãªãã¾ãï¼
1000 1000 1000 1000 -) 0000 0010 0011 0000 ---------------------- 1000 0110 0101 1000
å転ããã¾ãï¼
~) 1000 0110 0101 1000 ---------------------- 0111 1001 1010 0111
ãã¹ã¯ããã¶ãã¾ãï¼
0111 1001 1010 0111 &) 1000 1000 1000 1000 ---------------------- 0000 1000 1000 0000
æä¸ä½ãããã®ã¿ãç«ã¡ãããã¿ã¼ã³ã«å¸°çã§ãã¾ããã®ã§ï¼ãã¨ã¯æãç®ãªã©ã§ã§ãã¾ãï¼
ãããã«ããï¼summary
ãæ±ãããã¨ãã§ãã¾ããï¼
access
ä¸ä½ããæ°ã㦠0-indexed 㧠\(i\) çªç®ã®ãããã¯ã®æ´æ°ãåå¾ãããã¨ãã¯ã©ããã¾ããããï¼ é©å½ã«ã·ããããããã¹ã¯ããã¶ããã¨ããã§ããï¼
\(2\) çªç®ã®ãããã¯ãåå¾ãã¦ã¿ã¾ãããï¼
aaaa bbbb cccc dddd >>) 8 // 2*4 ----------------------- 0000 0000 aaaa bbbb
0000 0000 aaaa bbbb &) 0000 0000 0000 1111 ---------------------- 0000 0000 0000 bbbb
æ¬é¡
ãã¦ï¼æºåãæ´ãã¾ããï¼
確èªããã¨ï¼ç®æ¨ã¯ï¼\(w\) bits ã®æ´æ° x
ã® msb
ãæ±ãããã¨ã§ããï¼
ããã¯ï¼æ¬¡ã®ããã«ã§ãã¾ãï¼
以ä¸ã«ããã¦ï¼ãããã¯ã«ã¤ãã¦ã® msb
㯠log2p1
ããæ±ãã¾ãï¼
summary(x)
ã®msb
ãæ±ãï¼ããã \(i\) ã¨ããx
ã® \(i\) çªç®ã®ãããã¯ãåå¾ãï¼ãããb
ã¨ããb
ã®msb
ãæ±ãï¼ããã \(j\) ã¨ãã
ãã®ã¨ãï¼msb(x)
㯠\(i\sqrt{w}+j\) ã¨ãªãã¾ãï¼
ã½ã¼ã¹ã³ã¼ã
64-bit ã®ãã®ã®ã¤ããã§ãï¼
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; } uintmax_t popcount(uintmax_t n) { constexpr uintmax_t multiplier = 0x0101010101010101_ju; return (n * multiplier) >> 56; } uintmax_t minimsb(uintmax_t n) { if (n >= 0x80) return 7; constexpr uintmax_t multiplier = 0x0101010101010101_ju; uintmax_t minuend = n * multiplier; constexpr uintmax_t subtrahend = 0x8040201008040201_ju; uintmax_t rest = minuend - subtrahend; constexpr uintmax_t mask = 0x8080808080808080_ju; return popcount((~rest & mask) >> 7) - 1; } uintmax_t summary(uintmax_t n) { constexpr uintmax_t hi_mask = 0x8080808080808080_ju; constexpr uintmax_t lo_mask = 0x7F7F7F7F7F7F7F7F_ju; uintmax_t ones = (n | ~(hi_mask - (n & lo_mask))) & hi_mask; constexpr uintmax_t multiplier = 0x0002040810204081_ju; return (ones * multiplier) >> 56; } uintmax_t access(uintmax_t n, uintmax_t i) { constexpr uintmax_t mask = 0xFF_ju; return (n >> (i * 8)) & mask; } uintmax_t msb(uintmax_t n) { uintmax_t i = minimsb(summary(n)); uintmax_t j = minimsb(access(n, i)); return i * 8 + j; }
å®æ°æéã¢ã«ã´ãªãºã ãéãã¨ã¯è¨ã£ã¦ãªãç³»ã®ãã¤ã§ããï¼
å®æ¸¬
å ã¹ã©ã¤ãã®ãã®ã¯æ·»åãæ±ãããã®ã§ã¯ãªããï¼ããã«å¯¾å¿ããããã«ããæ°åã¯ä»ã®ãã³ã¡ããã«ã¯ãªãã®ã§ï¼æãåºãã¾ããï¼ãããï¼
1
以ä¸ã®æ´æ°ã std::mt19937_64
ã§ã©ã³ãã ã« \(10^7\) åçæãã¦ï¼ãããã® msb
ã®åè¨ãæ±ããæéã測ãã¾ãã*3ï¼
__builtin_clzll
ã«åã¦ã¾ããã§ããï¼
ãã¤ã¼ãã«ä¸ãã 1
ãè¦ã¤ããã¾ã§ãªããã®ã«ã¯åã¡ã¾ããï¼
æ¹æ³ | æé (ms) |
---|---|
built-in | 113.4 |
å®æ°æéãã | 188.2 |
ãã¤ã¼ã | 219.6 |
ãããã§ãï¼