#include <algorithm>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <utility>
std::pair<std::size_t,std::size_t> range(std::size_t n,std::size_t p,std::size_t t) {
    if(p==0 || t>=p) throw std::invalid_argument("partition");
    const auto q=n/p,r=n%p,begin=t*q+std::min(t,r);
    return {begin,begin+q+(t<r?1:0)};
}
int main() {
    for(std::size_t n=0;n<=257;++n) for(std::size_t p=1;p<=16;++p) {
        std::size_t previous=0;
        for(std::size_t t=0;t<p;++t) {
            const auto [begin,end]=range(n,p,t);
            if(begin!=previous || end<begin || end>n) throw std::runtime_error("coverage");
            previous=end;
        }
        if(previous!=n) throw std::runtime_error("last");
    }
    bool rejected=false;
    try {
        const auto [begin,end]=range(1,0,0);
        std::cout<<"unexpected zero-worker range=["<<begin<<','<<end<<")\n";
        return 1;
    } catch(const std::invalid_argument&){rejected=true;}
    if(!rejected) throw std::runtime_error("zero workers");
    std::cout<<"ranges=";
    for(std::size_t t=0;t<3;++t){auto [b,e]=range(10,3,t);std::cout<<(t?" ":"")<<'['<<b<<','<<e<<')';}
    std::cout<<'\n';
}
