ãªããè¨ç®é (amortized complexity) ã¨ããã®ãããã¾ããã競ããåå¿è 層ã«ã¯èª¤è§£ãããã¡ãªæ¦å¿µãªã®ã§ã誤解ã解ãããã®ãã¨ãæ¸ããããªãã¾ããã
以ä¸ã§ããããã誤解ãã¨ç§°ãã¦æ¶ç©ºã®äººç©ãããã¹ãã¾ãããè¤æ°åè¦ã¦ããäºä¾ã§ãããç¹å®å人ã«å¯¾ããæ¶æçã§ã¯ããã¾ããããã³ã¡ããèªèº«ã®äºä¾ã§ããå ´åãããã¾ã*1ã
å¤å°ç¥ã£ã¦ãã人ã¸ï¼ããã³ã·ã£ã«è§£æãªã©ã®è©±ãç´æ¥ã¯ããªãã®ã§ãããããã®ã¯å¥ã®è¨äºãè¦ã«è¡ã£ã¦ã»ããã§ããæç®ã®ç´¹ä»ãããã¯ããã¾ãã
- å°å ¥
- 説æ
- ããããä¾
- ãããµããªè©±
- ãªããããããã話
- ãªããã ã¨å°ã話
- ãªããè¨ç®éãããããã¼ã¿æ§é
- ã¾ã¨ã
- åèæç®
- ããã
å°å ¥
ãã¼ã¿æ§é ã®è¨ç®éãªã©ã§ã次ã®ãããªè¨è¿°ãè¦ããããã¨ãããããã¾ãã
vector
ã¸ã®ã¢ã¯ã»ã¹a[i]
ã¯ãææª \(O(1)\) æéset
ã§ã®äºåæ¢ç´¢a.lower_bound(x)
ã¯ãææª \(O(\log(n))\) æé
ãããã¯ããä¸çªæªãã¨ãã§ã \(O(1)\) æéã \(O(\log(n))\) æéã ããå®å¿ã ãªããã¨ããæ°æã¡ã§èªãã人ãå¤ããã§ãã
ä¸æ¹ã§ã次ã®ãããªè¨è¿°ãããããã¾ãã
vector
ã®æ«å°¾ã¸ã®è¿½åa.push_back(x)
ã¯ããªãã \(O(1)\) æé- åå´ \(O(1)\) æéã¨ããè¨ãæ¹ãããããããã¯åãæå³
- åæ§ã«ããªããè¨ç®éãåå´è¨ç®éã¨ãè¨ã
union_find
ã§ã®æä½a.unite(i, j)
ãa.find(i)
ã¯ããªãã \(O(\alpha(n))\) æé
ãããã¯ã誤解ãã¦ããªããã£ã¦ãªã«ï¼ ãã°ãã¨ã㯠\(O(1)\) æéã \(O(\alpha(n))\) æéã«ãªããªãã¦ãç¥ããªããã¡ã« TLE ã«ãªã£ãããããï¼ã§ä¸å®ã ãªããã¨ããæ°æã¡ã«ãªãåå¿è ãå¤ãå°è±¡ãããã¾ãã
å®éã«ã¯ãå°ãªãã¨ã競ããæèã§è¨ãã°ãããªãã㧠\(O(1)\) æéã \(O(\alpha(n))\) æéã ããå®å¿ã ãªããã¨ãªãããããã®ããããä¿è¨¼ãªã®ã§ããã®èª¬æããã¾ãã
説æ
ãæ°æã¡
ãã¼ã¿æ§é ã«å¯¾ã㦠\(n\) åæä½ãã\(n\) åã®åè¨ã®è¨ç®éã \(f(n)\) ã§ãã£ãã¨ããä¸åãããã®è¨ç®é㯠\(f(n)/n\) ã¨è¦ãªãã¾ãã ããã§ãå®éã®æä½ä¸åä¸åã®è¨ç®éã¯èããããã® \(f(n)/n\) ã«ã¤ãã¦èãã¦ã¿ããã¨ã«ãã¾ãã
ãã¨ãã° \(f(n) = O(n)\) ã§ããã°ãä¸åããã \(O(1)\) æéã¨ãããã¨ã«ãªãã¾ãã
ãããããå°ãã¡ããã¨ä¿è¨¼ãããã®ãããªããè¨ç®éã¨å¼ã°ãããã®ã§ãã
å®ç¾©ï¼ãããµãï¼
ãããã¼ã¿æ§é ã«å¯¾ãã¦è¡ããæä½ï¼vector
ã«å¯¾ãã push_back
ã¨ããstack
ã«å¯¾ãã push
ã»pop
ã¨ãï¼ãèãã¾ããããããã©ãããé çªã§ \(n\) åå¦çããå ´åã§ããåè¨ã \(f(n)\) æé以ä¸ã«ãªãã¨ãã¾ãããã®ã¨ãããããã®æä½ã¯ããªãã \(O(f(n)/n)\) æéãã§ããã¨è¨ãã¾ãã
ãã¨ãã°ããunion_find
ã«å¯¾ããæä½ã¯ãªãã \(O(\alpha(n))\) æéãã¨ããã®ã¯ããunion_find
ã«å¯¾ã㦠\(n\) åæä½ããã㨠\(O(n\cdot \alpha(n))\) æéãã®ãããªæå³åãã§ãã
å®ç¾©ï¼ãã£ã¡ããï¼
ãã¼ã¿æ§é ã«å¯¾ããä»»æã®æä½å \( (op_1, op_2, \dots, op_n)\) ãèãã¾ãï¼\(op_1\) ã .push_back(x)
ã¨ããããããæãã§ãï¼ã
ãã®ã¨ãã\(op_i\) (\(1\le i\le n\)) ã«å¯¾ãã¦ãå®éã®è¨ç®éã \(t(op_i)\) ã¨ãã¾ãã
ããã«ã\(a(op_i)\) ãåå¨ãã¦ãå \(1\le k\le n\) ã«å¯¾ãã¦ä»¥ä¸ãæãç«ã¤ã¨ãã¾ãã
\[
\sum_{i=1}^k t(op_i) \le \sum_{i=1}^k a(op_i).
\]
ãã®ã¨ãã\(a(op_i)\) ãï¼\(op_i\) ã®ï¼ãªããè¨ç®éã¨å¼ã³ã¾ãã
\(t(op_i) \le a(op_i)\) (\(1\le i\le n\)) ãæãç«ã¤å¿ è¦ã¯ãªãã\(i\) åç®ä»¥åã®æä½ã®åè¨ããæããããã°ããã®ããã½ã§ãã
\(n\) åã®æä½å ¨ä½ã®è¨ç®éã \(\sum_{i=1}^n a(op_i)\) ã§æããããããããã¨ãã° \(op_i\) ãããªãã \(O(\log(n))\) æéãã¨ä¿è¨¼ããã¦ããæä½ã§ããã°ãå ¨ä½ã§ \(O(n\log(n))\) æéã¨ããã£ããããããã§ãã
ï¼è£è¶³ï¼ ãã® \(a(op_i)\) ããã¾ããã¨æ±ããã®ããååé¡ã§ãªããè¨ç®éãæ±ããããã«å¿ è¦ãªãã¨ã§ããããªãã解æ (amortized analysis) ãªã©ã¨å¼ã°ãã¦ãããã®ã§ãã解æã®å ·ä½ä¾ã ããè¦ããããã¨å¤©æã«è¦ãã¾ãããå ¸åçãªææ³ãããã¤ãããã¾ãã
ããç´°ãã話
å®éã«ã¯ã\(n\) ããæä½åã®é·ãããªã®ãããã®æç¹ã®ãã¼ã¿æ§é ã®ãµã¤ãºããªã®ãããã以åã®ãã¼ã¿æ§é ã®ãµã¤ãºã®æ大å¤ããªã®ããã¼ããã¦è©±ããããããã¡ãªæ°ããã¾ãã
ã空ã®ç¶æ ããå§ãã¦ãæä½ãã¨ã«å¢ããè¦ç´ ã®åæ°ãé«ã 1 ã¤ãã§ãããããªå ´åã«ã¯ããã¼ã¿æ§é ã®ãµã¤ãºãæä½åã®é·ãã§ä¸ããæããããã®ã§ãåé¡ãªããããªæ°ããã¾ãã
ããã§ãªãå ´åã¯å°ãæ°ã«ããå¿ è¦ãããããããã¾ããã ããµã¤ãº \(n\) ã§åæåã㦠\(m\) åæä½ããããããªå ´åã«ã¯ãåæåã®è¨ç®é \(t(op_0)\) ãåããã¦èããããããã¾ããã ããã¾ãåæåã®ãã¨ãæ¸ãã¦ããæç®ã¯ãªãããããã¾ããã
\(\Theta\) ã¨ã \(\Omega\) ã¨ãã®è©±
ãªããè¨ç®éã®å®ç¾©ã ã¨ä¸ããããæãã¦ãªããã©ããªãã㧠\(\Theta\) ã \(\Omega\) ã£ã¦ãã¾ãå®ç¾©ããã¦ãï¼
ãããæä½åãåå¨ãã¦ãããä»»æã®æä½åã«å¯¾ãã¦ããã¯æèã«ãããããã ãã©ãä¸ããæããã°å®ç¾©ã§ããï¼ ã§ãããã
\(O\) 以å¤ãç¥ããªã人åã â ããé·ãã®è¨äº
ããããä¾
å¯å¤é·é å
vector
ã® .push_back
ã®ãããªãã®ã§ãããã£ãã以ä¸ã®ãããªã¢ã«ã´ãªãºã ã§ãã
- åããé·ã \(1\) ã®é åã確ä¿ãã
- 確ä¿ããé åã«æ°ããè¦ç´ ãç½®ãããªãç½®ãï¼\(O(1)\) æéï¼
- 確ä¿ããé åã足ããªããªã£ãããé·ããåã«ãã¦ããç½®ãï¼é åã®é·ãã \(k\) ã¨ã㦠\(\Theta(k)\) æéï¼
é·ã \(n\) ã«ããããã®è¨ç®éã¯ï¼ã¨ãªããã\(\Theta(n)\) æéã®æä½ããã£ã¦ \(n\) åã ãã \(\Theta(n^2)\) æéã...ï¼ãã¨ãã\(\Theta(n)\) æéã®æä½ã¯ \(\floor{\log_2(n)}\) åèµ·ãããã \(\Theta(n\log(n))\) æéã...ï¼ \(\log\) ã¯å®æ°ï¼ï¼ã ããä¸åããã \(O(1)\) æéã¨è¨ããã¦ããã ããªã®ã...ï¼ãã¨ãªã£ãããã¾ãããããã§ã¯ãªãã§ãã
é·ã \(k\) ã¯æ¯ååºå®ã§ã¯ãªã \(1 + 2 + 4 + \dots + 2^{\floor{\log_2(n)}}\) ã®ããã«ãªã£ã¦ãããããï¼çæ¯æ°åã®åã§ãããã¨ã«æ³¨æãããªã©ãã¦ï¼å ¨ä½ã§ \(\Theta(n)\) æéã§ãããã¨ããããã¾ãã
ãã¥ã¼
äºã¤ã®ã¹ã¿ãã¯ã§ãã¥ã¼ãä½ããã¨ãã§ããtwo-stack queue ãªã©ã¨å¼ã°ãã¾ã*2ã
ä¸ã®æ¹ã«ããã¹ã©ã¤ãã«ãè¼ã£ã¦ããã®ã§ã詳細ã¯å²æãã¾ããä¼¼ãæ¹æ³ã§ deque ãä½ãã¾ã*3ã
ã«ã¦ã³ã¿
\(0\) ããå§ã㦠\(n\) ã¾ã§ \(1\) ãã¤å¢ãããã¨ãèãã¾ãããã®ã¨ããåã¤ã³ã¯ãªã¡ã³ãã«å¯¾ãã¦ãæ°åãå¤åããæ¡ã¯ãªãã \(O(1)\) åã§ãããã¨ã示ãã¾ãã ãªã®ã§ãå¤ãã£ãæ¡ã®ã¿ããã¾ã管çãããã¨ã§ããã¨ãã°ä»¥ä¸ã®ãããªã¯ã¨ãªããªãã \(O(1)\) æéã§å¦çã§ãã¾ãã
- å¤ã \(1\) å¢ãã
- æ¡åãåºåãã
- ãããã¯æ¡ã®äºä¹åã¨ããåºåãã
ãããµããªè©±
ãªããã®ã¤ã¡ã¼ã¸ã®è©±ã§ãã
ãã¨ãã°ãã1 æ¥ã«ä½¿ã£ãéé¡ã 100 åãè¶ ãã¡ãããã¾ããããã¨ã1 é±éã«ä½¿ã£ãéé¡ã 700 åãè¶ ãã¡ãããã¾ããããã¨ããå¶éãèãã¾ãã å¾è ã¯ãå¹³æ¥ã¯ 1 åã使ããã«åæ¥ã« 350 åãã¤ä½¿ããã¨ãã£ãè¡åã許ãããã®ã«å¯¾ããåè ã§ã¯ãããããã¨ã許ããã¾ããã
ãã®åè ãææªè¨ç®éï¼åã¯ã¨ãªã®å®éã®è¨ç®éï¼ã«ç¸å½ããå¾è ããªããè¨ç®éï¼å ¨ä½ã§è¦ãã¨ãã«ä¸åãããã¨è¦ãªããè¨ç®éï¼ã«ç¸å½ããã¤ããã§ãã
ããå®æ ã«å³ãã¦ããã¤ã¡ã¼ã¸ããã©ãã®ã«ããã£ãã®ã§æ¸ãã¾ããåè ã¯ãæ¯æ¥ 100 åãã¤ããããã©ã使ããªãã£ãã¶ãã¯æ²¡åããã§ãå¾è ã¯ãæ¯æ¥ 100 åãã¤ãããããã使ã£ã¦ã貯éãã¦ããããï¼åéã¯ã ããå©åã¯ãªãï¼ãã§ããè¨ç®éãå°ããæä½ãããã®ã貯éãä½ã£ããã¨ã«ç¸å½ãã¾ãã
ãªããããããã話
ãªããè¨ç®éã解æã®é¢ã§ããããç¶æ³ã¨ãã¦ã¯ã
- ä¸åä¸åã®è§£æã¯é£ããããå ¨ä½ã§è¦ãã°è§£æãç°¡å
- éãã¯ã¨ãªãããããå ¨ä½ã§è¦ãã°åå軽ã
ã®ãããªãã®ãããã¾ããããã¯ããã¨ãã¦ããå ¨ä½ã¨ãã¦ã®è¨ç®éããä¿è¨¼ããã°ããã¨ãã¯ããªããã ãä¿è¨¼ããããã«è¨è¨ãããã¨ããæ¹éãããããã±ã¼ã¹ãããã¾ãã
ãã¨ãã°ã\(n\) åã®æä½ã®è¨ç®éã \( (1, 1, \dots, 1, n)\) ã§åè¨ \(2n-1\) ã«ãªã£ã¦ãããã¼ã¿æ§é ããã£ãã¨ãã¾ãã ããã¯ãªãã \(O(1)\) æéã§ãããææª \(O(1)\) æéã§ã¯ããã¾ããï¼æå¾ã®ä¸åã \(n\) ã«ãªã£ã¦ããã®ã§ï¼ã
ããããªãã¨ã工夫ãããã¨ã§ \( (10, 10, \dots, 10, 10)\) ã«ã§ããã¨ãã¾ããããã¯ææª \(O(1)\) æéãä¿è¨¼ã§ãã¦ãã¾ãããåè¨ã¨ãã¦ã¯ \(10n\) ã«å¢ãã¦ãã¾ã£ã¦ãã¾ãã
ãã®ã¨ããå®æ°åãæªããªã£ã¦ããä¸ãå ¨ä½ã®ãªã¼ãã¼ãæ¹åããã¦ããããã§ããªããå®è£ ã®å·¥å¤«ãå¿ è¦ã«ãªã£ã¦ãã¾ãã大å¤ã¥ããã§ãã
ãã¡ãããææªè¨ç®éãä¿è¨¼ããããã«å¿ ãããå®æ°åãããã£ã¡ãã£ã«æªåããããã§ã¯ãªãã®ã§ç¶æ³ã«ããããã§ããããããå¶éã§ãããªãããã«å¿ãã¦ãã¾ãããã¾ãããã¨ãããã¨ã§ãã
ãªããã ã¨å°ã話
競ããã ã¨ããã¾ããªãã¨æãã¾ãã
ãã¨ãã°ãWeb ãµã¤ããªã©ã§ã\(i\) çªç®ã®ã¢ã¯ã»ã¹ã«å¯¾ãã¦ã¯ããã¼ã¿æ§é ã«å¯¾ãã¦å¦ç \(i\) ãè¡ããã¨ããå¦çããã£ãã¨ãã¾ãã ãã®ã¨ãããªããè¨ç®éããä¿è¨¼ããã¦ããªãã¨ãä¸é¨ã®ã¦ã¼ã¶ãããã¡ããã¡ãæéããã£ããã¨ãããããªä½é¨ããããã¨ã«ãªãããã¾ããããããªãããã§ãã
競ããã§ãå°ãä¾ããã©ãã®ã«ããã£ãã®ã§æ¸ãã¾ãã ããªããââæéãã®æä½ãæ®éã«ããã ããªãåé¡ãªãã¨æãã¾ãããrollback ãå¯è½ãªãã¼ã¿æ§é ã«æ¸ãæãããã¨ããã¨ãã«ãå ãããªãããã®ãã¼ã¿æ§é ã ã¨ã¤ãããã¨ãããã¾ãã
å ã®ã«ã¦ã³ã¿ã®ä¾ã§è¨ãã°ã999...9 ããï¼å¤§ããè¨ç®éã§ï¼1000...0 ã«æ´æ°ãããã¨ãrollback ããã¦ï¼å¤§ããè¨ç®éã§ï¼999...9 ã«æ»ããã¾ãï¼å¤§ããè¨ç®éã§ï¼1000...0 ã«æ´æ°ãã¦ã... ã¨ããã®ãç¹°ãè¿ãã¨ãæ¯å大ããè¨ç®éããããããã«ãªãã¾ããã
ã¨ã¯ãããããªããââæéãã¨ä¿è¨¼ããã¦ãããã¼ã¿æ§é ããä¿è¨¼ããã¦ããéãã«ä½¿ãã°åé¡ãªããã¨ã«ã¯å¤ãããªãæ°ã¯ãã¾ãã
ãªããè¨ç®éãããããã¼ã¿æ§é
C++/STL ã«ãããããããã¾ããã
vector
ã®.push_back(x)
ã¯ãªãã \(O(1)\) æé- ãã®ããã§ã
vector
ãå é¨ã§ä½¿ããã¼ã¿æ§é ã¯å¤§æµãªããã«ãªããã¡
- ãã®ããã§ã
set
ã®.erase(it)
ã¯ãªãã \(O(1)\) æé- ã³ã¹ãã
.insert(x)
ã«æ¼ãã¤ãããã¨ã§ã.erase(it)
ã®æ¹ã¯ãªããããï¼ - ããã¯ããã¨ãã¦ã赤é»æ¨ã平衡ãããæä½ã¯ãªãã \(O(1)\) æé
- ã©ãã«æ¿å ¥ã»åé¤ãããã¯ããã¤ã³ã¿ãªã©ãæã£ã¦ããªã㨠\(O(1)\) ã§æ±ºããããªããã¨ã«æ³¨æ
it
ã¯ã¤ãã¬ã¼ã¿
- ã³ã¹ãã
STL ã§ã¯ãªããã®ã®ç«¶ããã§ãããããã¼ã¿æ§é ã«ãããããããã¾ãã
union_find
ã®.unite(i, j)
ã.find(i)
ã¯ï¼é©åã«å®è£ ããã°ï¼ãªãã \(O(\alpha(n))\) æé- å®éã«ã¯ããµã¤ãº \(n\) ã®ããã« \(m\) åæä½ãã㨠\(\Theta(n+m\,\alpha(m, n))\) æéã§ã\(O(\alpha(n))\) æéãããå³ããæãããã
- \(\alpha(m, n)\) ã«ã¤ãã¦ã¯ â ããããè¨äº
foldable_queue
ã®.fold()
ã.push(x)
ã¯ãªãã \(O(1)\) æé- ãããã SWAGï¼ãåæã«ããå¼ãã§ãã¾ãï¼
- queue ã¸ã® push/pop ã¨ãå ¨ä½ã®ã¢ãã¤ãç© (fold) ãå¦çãããã¼ã¿æ§é
- push 㨠fold ã¯ææª \(O(1)\) æé
- two-stack queue ãå¿ç¨ãã¦å®è£ ããï¼ã®ã§ deque ã§ãå¯è½ï¼
- ãããã SWAGï¼ãåæã«ããå¼ãã§ãã¾ãï¼
decremental_neighbor_query
ã®.less_than(i)
ã.greater_equal(i)
ãªã©ã¯ããªãã \(O(1)\) æé- \(\{1, 2, \dots, n\}\) ã§åæåããéåã«å¯¾ããåé¤æä½ã¨ãé£ã®è¦ç´ ã®æ¤ç´¢ãã§ãã
skew_heap
ã®.meld(q)
ã¯ãªãã \(O(\log(n))\) æé- ãã¼ãï¼åªå 度ã¤ããã¥ã¼ï¼äºã¤ã«å¯¾ãã¦ããããããã£ã¤ãã¦ä¸ã¤ã®ãã¼ãã«ããæä½ã meld ã¨å¼ã¶
fibonacci_heap
ã®.prioritize(it, k)
ã¯ãªãã \(O(1)\) æé- ãã¼ãã«å¯¾ãã¦ãããè¦ç´ ã®åªå
度ãé«ããæä½ï¼åãåºãããããããï¼ã prioritize ã¨åæã«å¼ãã§ãã¾ã
- æç®ã«ãã£ã¦ã¯
decrease_key
ã¨ãè¨ããã
- æç®ã«ãã£ã¦ã¯
- ãã®æä½ã \(O(1)\) æéã§ã§ãããã¨ã«ãããDijkstra æ³ã®è¨ç®éã \(O(|E|\log(|V|))\) ãã \(O(|E|+|V|\log(|V|))\) ã«æ¹åã§ãã
- ãã¼ãã«å¯¾ãã¦ãããè¦ç´ ã®åªå
度ãé«ããæä½ï¼åãåºãããããããï¼ã prioritize ã¨åæã«å¼ãã§ãã¾ã
ã¾ã¨ã
ãªããè¨ç®éã¯ãæä½åãå ¨ä½ã¨ãã¦è¦ãã¨ãã®è¨ç®éãä¿è¨¼ãã¦ãããããã競ããæèã§ã¯ãææªââæéãã¨åç¨åº¦ã«ãããä¿è¨¼ã¨è¦ãªãã¦ããã§ãã ãå ¥åã«ãã£ã¦ã¯ââæéã«ãªã£ã¦ããã TLEï¼å¹³åè¨ç®éï¼ãã¨ããä¹±æ°ã®å¤ã«ãã£ã¦ã¯ââæéã«ãªã£ã¦ããã TLEï¼æå¾ è¨ç®éï¼ãã¨ãã¨ã¯äºæ ãç°ãªãã¾ãã
åèæç®
- cs166.1266
- å³ã¨ãããã®ããæãã®è¬ç¾©ã¹ã©ã¤ã
- ä»ã«ããããããªãããã¯ããã
- ç¨æè¢ã®è¨äº
- ãªãã以å¤ã«ããæå¾ è¨ç®éãå¹³åè¨ç®éã«ã¤ãã¦ãè¼ã£ã¦ãã
ããã
ã«ãããã
*1:ããããæå³ã§ã¯ç¹å®å人ã§ãããèªåãªã®ã§è¨±ããã¾ãã
*2:ææ³ã¨ãã¦ã¯ãtwo-week vacation ã¨ãã®ããã«ããã¤ãã³ã§æ°è©ã¨ã¤ãªãã§åè©ãåæ°å½¢ã«ãªã形容è©ã®ãã¤ã§ããtwo-stacks queue ã two-stack-queue ã§ã¯ãªãã§ãã
*3:æ¦è¦ï¼çæ¹ã空ã«ãªã£ãã¨ãã« \(k\) å移ãã®ã§ã¯ãªã \(\ceil{k/2}\) å移ãã¾ãã