C++ Fish
#include <vector>

int fish(const std::vector<int>& a, const std::vector<int>& b)
{
    int size = static_cast<int>(a.size());
    int dead = 0;
    std::vector<int> downstream;

    for (int i = 0; i < size; ++i) {
        if (b[i] == 1) {
            downstream.push_back(a[i]);
        } else if (!downstream.empty()) {
            while (!downstream.empty()) {
                ++dead;
                if (a[i] > downstream.back()) {
                    downstream.pop_back();
                } else {
                    break;
                }
            }
        }
    }

    return size - dead;
}

This uses a stack for downstream fish and resolves fights only when opposite directions meet.