#pragma once
// SPDX-License-Identifier: Apache-2.0// This file includes code derived from Library Checker Problems:// https://github.com/yosupo06/library-checker-problems/blob/1e3da4fd4135f4f3cb3a6d76b51c827f7d987942/common/random.h//// The original work is licensed under the Apache License, Version 2.0.//// Local modifications in this repository:// - Moved #pragma once to the first line for oj-bundle compatibility.// - Made this header self-contained by adding missing standard library// includes and removing an unused include.#include<algorithm>
#include<array>
#include<cassert>
#include<cstddef>
#include<cstdint>
#include<numeric>
#include<set>
#include<string>
#include<utility>
#include<vector>structRandom{private:// Use xoshiro256**// References: http://xoshiro.di.unimi.it/xoshiro256starstar.cstaticuint64_trotl(constuint64_tx,intk){return(x<<k)|(x>>(64-k));}std::array<uint64_t,4>s;uint64_tnext(){constuint64_tresult_starstar=rotl(s[1]*5,7)*9;constuint64_tt=s[1]<<17;s[2]^=s[0];s[3]^=s[1];s[1]^=s[2];s[0]^=s[3];s[2]^=t;s[3]=rotl(s[3],45);returnresult_starstar;}// random choice from [0, upper]uint64_tnext(uint64_tupper){if(!(upper&(upper+1))){// b = 00..0011..11returnnext()&upper;}intlg=63-__builtin_clzll(upper);uint64_tmask=(lg==63)?~0ULL:(1ULL<<(lg+1))-1;while(true){uint64_tr=next()&mask;if(r<=upper)returnr;}}public:Random(uint64_tseed=0){// Use splitmix64// Reference: http://xoshiro.di.unimi.it/splitmix64.cfor(inti=0;i<4;i++){uint64_tz=(seed+=0x9e3779b97f4a7c15);z=(z^(z>>30))*0xbf58476d1ce4e5b9;z=(z^(z>>27))*0x94d049bb133111eb;s[i]=z^(z>>31);}}// random choice from [lower, upper]template<classT>Tuniform(Tlower,Tupper){assert(lower<=upper);returnT(lower+next(uint64_t(upper-lower)));}// random choice from false or truebooluniform_bool(){returnuniform(0,1)==1;}// random choice from [0.0, 1.0]doubleuniform01(){uint64_tv=next(1ULL<<63);returndouble(v)/(1ULL<<63);}// random choice non-empty sub-interval from interval [lower, upper)// equal: random choice 2 disjoint elements from [lower, upper]template<classT>std::pair<T,T>uniform_pair(Tlower,Tupper){assert(upper-lower>=1);Ta,b;do{a=uniform(lower,upper);b=uniform(lower,upper);}while(a==b);if(a>b)std::swap(a,b);return{a,b};}// generate random lower string that length = nstd::stringlower_string(std::size_tn){std::stringres="";for(std::size_ti=0;i<n;i++){res+=uniform('a','z');}returnres;}// random shuffletemplate<classIter>voidshuffle(Iterfirst,Iterlast){if(first==last)return;// Reference and edit:// cpprefjp - C++日本語リファレンス// (https://cpprefjp.github.io/reference/algorithm/shuffle.html)intlen=1;for(autoit=first+1;it!=last;it++){len++;intj=uniform(0,len-1);if(j!=len-1)iter_swap(it,first+j);}}// generate random permutation that length = ntemplate<classT>std::vector<T>perm(std::size_tn){std::vector<T>idx(n);std::iota(idx.begin(),idx.end(),T(0));shuffle(idx.begin(),idx.end());returnidx;}// random choice n elements from [lower, upper]template<classT>std::vector<T>choice(std::size_tn,Tlower,Tupper){assert(T(n)<=upper-lower+1);std::set<T>res;while(res.size()<n)res.insert(uniform(lower,upper));return{res.begin(),res.end()};}}global_gen;
#line 2 "random_graph/random.hpp"
// SPDX-License-Identifier: Apache-2.0// This file includes code derived from Library Checker Problems:// https://github.com/yosupo06/library-checker-problems/blob/1e3da4fd4135f4f3cb3a6d76b51c827f7d987942/common/random.h//// The original work is licensed under the Apache License, Version 2.0.//// Local modifications in this repository:// - Moved #pragma once to the first line for oj-bundle compatibility.// - Made this header self-contained by adding missing standard library// includes and removing an unused include.#include<algorithm>
#include<array>
#include<cassert>
#include<cstddef>
#include<cstdint>
#include<numeric>
#include<set>
#include<string>
#include<utility>
#include<vector>structRandom{private:// Use xoshiro256**// References: http://xoshiro.di.unimi.it/xoshiro256starstar.cstaticuint64_trotl(constuint64_tx,intk){return(x<<k)|(x>>(64-k));}std::array<uint64_t,4>s;uint64_tnext(){constuint64_tresult_starstar=rotl(s[1]*5,7)*9;constuint64_tt=s[1]<<17;s[2]^=s[0];s[3]^=s[1];s[1]^=s[2];s[0]^=s[3];s[2]^=t;s[3]=rotl(s[3],45);returnresult_starstar;}// random choice from [0, upper]uint64_tnext(uint64_tupper){if(!(upper&(upper+1))){// b = 00..0011..11returnnext()&upper;}intlg=63-__builtin_clzll(upper);uint64_tmask=(lg==63)?~0ULL:(1ULL<<(lg+1))-1;while(true){uint64_tr=next()&mask;if(r<=upper)returnr;}}public:Random(uint64_tseed=0){// Use splitmix64// Reference: http://xoshiro.di.unimi.it/splitmix64.cfor(inti=0;i<4;i++){uint64_tz=(seed+=0x9e3779b97f4a7c15);z=(z^(z>>30))*0xbf58476d1ce4e5b9;z=(z^(z>>27))*0x94d049bb133111eb;s[i]=z^(z>>31);}}// random choice from [lower, upper]template<classT>Tuniform(Tlower,Tupper){assert(lower<=upper);returnT(lower+next(uint64_t(upper-lower)));}// random choice from false or truebooluniform_bool(){returnuniform(0,1)==1;}// random choice from [0.0, 1.0]doubleuniform01(){uint64_tv=next(1ULL<<63);returndouble(v)/(1ULL<<63);}// random choice non-empty sub-interval from interval [lower, upper)// equal: random choice 2 disjoint elements from [lower, upper]template<classT>std::pair<T,T>uniform_pair(Tlower,Tupper){assert(upper-lower>=1);Ta,b;do{a=uniform(lower,upper);b=uniform(lower,upper);}while(a==b);if(a>b)std::swap(a,b);return{a,b};}// generate random lower string that length = nstd::stringlower_string(std::size_tn){std::stringres="";for(std::size_ti=0;i<n;i++){res+=uniform('a','z');}returnres;}// random shuffletemplate<classIter>voidshuffle(Iterfirst,Iterlast){if(first==last)return;// Reference and edit:// cpprefjp - C++日本語リファレンス// (https://cpprefjp.github.io/reference/algorithm/shuffle.html)intlen=1;for(autoit=first+1;it!=last;it++){len++;intj=uniform(0,len-1);if(j!=len-1)iter_swap(it,first+j);}}// generate random permutation that length = ntemplate<classT>std::vector<T>perm(std::size_tn){std::vector<T>idx(n);std::iota(idx.begin(),idx.end(),T(0));shuffle(idx.begin(),idx.end());returnidx;}// random choice n elements from [lower, upper]template<classT>std::vector<T>choice(std::size_tn,Tlower,Tupper){assert(T(n)<=upper-lower+1);std::set<T>res;while(res.size()<n)res.insert(uniform(lower,upper));return{res.begin(),res.end()};}}global_gen;