Если не в вычислительном плане, то в семантическом уж точно (потом намного труднее будет разобраться что там к чему)
Так часто бывает: или красиво, или быстро.
Для повышения удобочитаемости я бы
1) писал не
а
2) Дал переменным более длинные, но понятные имена - через месяц вы забудете, что такое fe и о чем маякует флаг
3) Расставил фигурные скобки для циклов и условий даже если в их теле только одна операция
4) Использовал std::vector (или сделал свой аналог) вместо массивов - нет необходимости думать о delete и некоторые другие плюшки.
и дополнительное логическое "и"
Вторая проверка сработает только если первая проверка даст true. Поэтому, кстати, будет работать быстрее, если в случае логического "и" первой проверкой ставить ту, что чаще false, чтобы не проверять вторую, а в случае логического "или" наоборот.
Здесь его, конечно можно сделать bool, но на 64 битной машине от этого толку не особо.
Разница есть. Короткие типы, требуют меньше памяти и если массив большой, то его куски реже надо будет подгружать в кэш. Если же вы решите векторизовать проверки, то это станет еще более критичным. Я бы без векторизации делал char.
Представим, что вы завели отдельный массив, в котором отмечаете, какие элементы проверять надо, а какие нет.
1) В процессе работы могут проверяемые стать непроверяемыми? А наоборот?
2) Какое хотя бы примерное соотношение тех, что надо проверять и тех, что не надо?
3) О каких вообще размерах массивов хотя бы примерно идет речь?