#pragma once
#include<algorithm>
#include<utility>usingnamespacestd;namespaceRadixSortImpl{constexprintb=8;constexprintpowb=1<<b;constexprintmask=powb-1;intcnt0[powb];intcnt1[powb];intcnt2[powb];intcnt3[powb];template<typenameT>voidradix_sort(intN,T*p){static_assert(sizeof(T)==4orsizeof(T)==8);if(!N)return;if(N<=64){sort(p,p+N);return;}staticT*tmp=nullptr;staticinttmp_size=0;if(!tmportmp_size<N){if(tmp)delete[]tmp;tmp_size=1;while(tmp_size<N)tmp_size*=2;tmp=newT[tmp_size];}memset(cnt0,0,sizeof(cnt0));memset(cnt1,0,sizeof(cnt1));memset(cnt2,0,sizeof(cnt2));memset(cnt3,0,sizeof(cnt3));for(inti=0;i<N;i++){cnt0[p[i]&mask]++;cnt1[(p[i]>>b)&mask]++;cnt2[(p[i]>>b*2)&mask]++;cnt3[(p[i]>>b*3)&mask]++;}for(inti=0;i<powb-1;i++){cnt0[i+1]+=cnt0[i];cnt1[i+1]+=cnt1[i];cnt2[i+1]+=cnt2[i];cnt3[i+1]+=cnt3[i];}for(inti=N;i--;)tmp[--cnt0[p[i]&mask]]=p[i];for(inti=N;i--;)p[--cnt1[tmp[i]>>b&mask]]=tmp[i];for(inti=N;i--;)tmp[--cnt2[p[i]>>b*2&mask]]=p[i];for(inti=N;i--;)p[--cnt3[tmp[i]>>b*3&mask]]=tmp[i];ifconstexpr(sizeof(T)==8){memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i]>>b*4&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i]>>b*4&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i]>>b*5&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i]>>b*5&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i]>>b*6&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i]>>b*6&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i]>>b*7&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i]>>b*7&mask]]=tmp[i];}ifconstexpr(is_signed<T>::value){inti=N;while(iandp[i-1]<0)i--;rotate(p,p+i,p+N);}}// N 10^7 int : 90 ms// N 10^7 ll : 220 mstemplate<typenameT>voidradix_sort(vector<T>&v){radix_sort(v.size(),v.data());}// first の順にソート, second は不問template<typenameT,typenameU>voidradix_sort_compare_first(intN,pair<T,U>*p){static_assert(sizeof(T)==4orsizeof(T)==8);if(!N)return;if(N<=64){stable_sort(p,p+N,[](constpair<T,U>&s,constpair<T,U>&t){returns.first<t.first;});return;}staticpair<T,U>*tmp=nullptr;staticinttmp_size=0;if(!tmportmp_size<N){if(tmp)delete[]tmp;tmp_size=1;while(tmp_size<N)tmp_size*=2;tmp=newpair<T,U>[tmp_size];}memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*2&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*2&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*3&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*3&mask]]=tmp[i];ifconstexpr(sizeof(T)==8){memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*4&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*4&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*5&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*5&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*6&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*6&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*7&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*7&mask]]=tmp[i];}ifconstexpr(is_signed<T>::value){inti=N;while(iandp[i-1].first<0)i--;rotate(p,p+i,p+N);}}// first の順にソート, second は不問// N 10^7 int : 130 ms// N 10^7 ll : 370 mstemplate<typenameT,typenameU>voidradix_sort_compare_first(vector<pair<T,U>>&v){radix_sort_compare_first(v.size(),v.data());}}// namespace RadixSortImplusingRadixSortImpl::radix_sort;usingRadixSortImpl::radix_sort_compare_first;/*
@brief radix sort
*/
#line 2 "math-fast/radix-sort.hpp"
#include<algorithm>
#include<utility>usingnamespacestd;namespaceRadixSortImpl{constexprintb=8;constexprintpowb=1<<b;constexprintmask=powb-1;intcnt0[powb];intcnt1[powb];intcnt2[powb];intcnt3[powb];template<typenameT>voidradix_sort(intN,T*p){static_assert(sizeof(T)==4orsizeof(T)==8);if(!N)return;if(N<=64){sort(p,p+N);return;}staticT*tmp=nullptr;staticinttmp_size=0;if(!tmportmp_size<N){if(tmp)delete[]tmp;tmp_size=1;while(tmp_size<N)tmp_size*=2;tmp=newT[tmp_size];}memset(cnt0,0,sizeof(cnt0));memset(cnt1,0,sizeof(cnt1));memset(cnt2,0,sizeof(cnt2));memset(cnt3,0,sizeof(cnt3));for(inti=0;i<N;i++){cnt0[p[i]&mask]++;cnt1[(p[i]>>b)&mask]++;cnt2[(p[i]>>b*2)&mask]++;cnt3[(p[i]>>b*3)&mask]++;}for(inti=0;i<powb-1;i++){cnt0[i+1]+=cnt0[i];cnt1[i+1]+=cnt1[i];cnt2[i+1]+=cnt2[i];cnt3[i+1]+=cnt3[i];}for(inti=N;i--;)tmp[--cnt0[p[i]&mask]]=p[i];for(inti=N;i--;)p[--cnt1[tmp[i]>>b&mask]]=tmp[i];for(inti=N;i--;)tmp[--cnt2[p[i]>>b*2&mask]]=p[i];for(inti=N;i--;)p[--cnt3[tmp[i]>>b*3&mask]]=tmp[i];ifconstexpr(sizeof(T)==8){memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i]>>b*4&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i]>>b*4&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i]>>b*5&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i]>>b*5&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i]>>b*6&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i]>>b*6&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i]>>b*7&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i]>>b*7&mask]]=tmp[i];}ifconstexpr(is_signed<T>::value){inti=N;while(iandp[i-1]<0)i--;rotate(p,p+i,p+N);}}// N 10^7 int : 90 ms// N 10^7 ll : 220 mstemplate<typenameT>voidradix_sort(vector<T>&v){radix_sort(v.size(),v.data());}// first の順にソート, second は不問template<typenameT,typenameU>voidradix_sort_compare_first(intN,pair<T,U>*p){static_assert(sizeof(T)==4orsizeof(T)==8);if(!N)return;if(N<=64){stable_sort(p,p+N,[](constpair<T,U>&s,constpair<T,U>&t){returns.first<t.first;});return;}staticpair<T,U>*tmp=nullptr;staticinttmp_size=0;if(!tmportmp_size<N){if(tmp)delete[]tmp;tmp_size=1;while(tmp_size<N)tmp_size*=2;tmp=newpair<T,U>[tmp_size];}memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*2&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*2&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*3&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*3&mask]]=tmp[i];ifconstexpr(sizeof(T)==8){memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*4&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*4&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*5&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*5&mask]]=tmp[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[p[i].first>>b*6&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)tmp[--cnt0[p[i].first>>b*6&mask]]=p[i];memset(cnt0,0,sizeof(cnt0));for(inti=0;i<N;i++)cnt0[tmp[i].first>>b*7&mask]++;for(inti=0;i<powb-1;i++)cnt0[i+1]+=cnt0[i];for(inti=N;i--;)p[--cnt0[tmp[i].first>>b*7&mask]]=tmp[i];}ifconstexpr(is_signed<T>::value){inti=N;while(iandp[i-1].first<0)i--;rotate(p,p+i,p+N);}}// first の順にソート, second は不問// N 10^7 int : 130 ms// N 10^7 ll : 370 mstemplate<typenameT,typenameU>voidradix_sort_compare_first(vector<pair<T,U>>&v){radix_sort_compare_first(v.size(),v.data());}}// namespace RadixSortImplusingRadixSortImpl::radix_sort;usingRadixSortImpl::radix_sort_compare_first;/*
@brief radix sort
*/