A ja bym poszedł innym tropem. Po pierwsze, nie liczyłbym miesięcy, tylko dni. No chyba że masz miesiące - ale co w przypadku, kiedy nieobecność trwa pół miesiąca (od 1szego do 15tego), a drugą połowę delikwent chodzi do pracy? Jeżeli przeliczasz na 0.5, to mój sposób może zadziałać.
A na czym mój sposób bazuje? Na lekkim brute-force, niestety

Ale jest po pierwsze: skuteczny, po drugie: znacznie szybszy od Twojego (przetwarza 100 wpisów urlopowych w 0.02 sekundy, tak mi przynajmniej zeznaje microtime).
I mimo że nie lubię rzucać gotowym kodem, to tym razem chyba się nie da. Za to komentarza nie będzie, bo powinien dokumentować się sam.

<?php
'1' => array ('from' => '2012-01-01', 'to' => '2012-06-31'), '2' => array ('from' => '2012-04-01', 'to' => '2012-07-31'), '3' => array ('from' => '2012-05-01', 'to' => '2012-05-31'), '4' => array ('from' => '2012-10-01', 'to' => '2012-11-31'), [... i tak dalej...]
);
foreach ($urlopy as $idx=>$okres) {
list
($year,$month,$day) = explode ('-', $okres['from']); $od = date ('z', mktime (0
, 0
, 0
, $month, $day, $year));
list
($year,$month,$day) = explode ('-', $okres['to']); $do = date ('z', mktime (0
, 0
, 0
, $month, $day, $year));
for ($i=$od; $i<=$do; $i++) {
$urlopy_dni[$i] = 1;
}
}
echo 'Całkowitych urlopów: ' . count ($urlopy_dni) . ' dni<br>';
Hm, w zasadzie to przerobienie na liczenie miesięcy nie będzie takie trudne. Po explode pomijamy części $year i $day, tablicę $urlopy_dni zmieniamy np. na $urlopy_miesiace, o date i mktime zapominamy, a do tablicy wpisujemy "1", jeśli zahaczyliśmy o miesiąc. Tylko że znowu pozostaje pytanie: czy tydzień urlopu od 2012-02-27 do 2012-03-04 to "tylko" 5 dni urlopu czy "aż" dwa miesiące? Bo to chyba nie będzie to samo...
EDITTak czytam jeszcze raz oryginalny post z problemem... i tak sobie myślę... najpierw dopisywanie, potem usuwanie duplikatów... Strasznie to skomplikowane - dopisywanie jest proste, owszem. Ale usuwanie duplikatów z tablicy, i to tak skonstruowanej jak u Ciebie? Bierzemy pierwszy element z pierwszej tablicy i szukamy go we wszystkich tablicach i usuwamy. Potem drugi element z pierwszej, trzeci. A potem pierwszy element z drugiej, tak? No to złożoność obliczeniową masz mega

Rada: zmodyfikuj lekko swój algorytm i nie dodawaj całych dat, tylko rozbij to na rok i miesiąc i twórz indeksy i używaj w postaci
$urlop[$rok.'-'.$mc] = 1
Ustawienie zmiennej nawet kilka tysięcy razy będzie dużo szybsze niż przeszukiwanie tablicy. A do liczenia elementów swojej tablicy masz szybkie i wygodne count()