Si è vero, è logicamente sbagliato, se uno è occupato dall'11 al 13 ma libero il 14, quel codice te lo ritorna come disponibile. Ma perchè non sbarazzarsi del ciclo for?? ->(altrimenti bisogna mettere nell'array quelli liberi e poi contare quelli che sono stati scritti un numero di volte cuguale al numero di giorni dell'intervallo, una specie di contatore come dicevi tu).

Codice PHP:
$da "data_di_inizio_ricerca";
$a "data_di_fine_riecerca";
$table_tutor "nome_tabella_tutor";
$table_impegnati "nome_tabella_tutor_impegnati";
$query "SELECT DISTINCT(tg.id_tutor) AS tid, tg.id_name AS tname FROM $table_tutor AS tg WHERE tg.id_tutor NOT IN(SELECT id_tutor FROM $table_impegnati WHERE (dal>='$da' AND dal<='$a') OR (al>='$da' AND al<='$a') OR (dal<='$da' AND al>='$a')";
$querymysql_query($query);
$tot=mysql_num_rows($query);

while (
$a_row mysql_fetch_array($query)) {
    
$tid $a_row['tid'];
    
$tname $a_row['tname'];
    if(!
in_array($tname$array)) $array[$tid] = $tname;

La clausola where si compone di tre parti:
1 - becco tutti quelli impegnati a cavallo della data $da
2 - becco tutti quelli impegnati a cavallo della data $a
3 - becco quelli impegnati in mezzo all'intervallo

Come prima ocio agli errori di punteggiatura.
Nota: le clausole le ho scritte in fretta, forse si possono ottimizzare, ma sai... sto lavorando...