Du brauchst in $new kein 2D-Array, die Subnetze bilden per Definition einen präfixfreien Code. Die errechneten $iplong-Werte in f dürften bei realitätsnahen Inhalten im $a Array keine Doubletten bilden. Es sei denn, du hantierst mit historischen Daten und hast Subnetzangaben, die später aufgeteilt wurden.
Du solltest auch den ip2long Wert nach rechts shiften, sondern aus der Präfixlänge die Subnetzmaske bestimmen (über eine Lookup-Tabelle) und dann $iplong & $subnetmask als Key für $a2 verwenden. Dann kannst Du in g nämlich über alle 31 möglichen Subnetzmasken gehen und mit array_key_exists in $a2 prüfen, ob $b & $subnetmask enthalten ist. Bei vielen Einträgen in $a ist das effizienter.
Eine weitere Optimierung wäre, in $a die tatsächlich genutzten Subnetzmasken als Keys eines Arrays zu sammeln und in g nur diese für die Suche zu nutzen.
Rolf