Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
random.hpp
[詳解]
1#pragma once
2#include"../../kyopro_library/template.hpp"
3#include"../../kyopro_library/others/xor128.hpp"
4
5/// @brief ランダムテストケース生成
6namespace RandomGenerator {
7 /// @brief 0 以上 n 未満のランダムな整数を返す
8 template<typename T>
9 T RandomInt(T n) { return Xor128(n); }
10
11 /// @brief [l, r) の範囲からランダムな整数を返す
12 template<typename T>
13 T RandomInt(T l, T r) { return Xor128(l,r); }
14
15 /// @brief 配列 a からランダムな要素を取得し、削除する
16 template<typename T>
17 T GetRandomElement(vector<T>& a) {
18 const int n=a.size();
19 int idx=RandomInt(0,n);
20 swap(a[n-1],a[idx]);
21 int ret=a.back();
22 a.pop_back();
23 return ret;
24 }
25
26 /// @brief 長さ n の [lo, hi) の要素からなるランダムな数列を返す
27 /// @param no_dup false の場合、重複要素を許容する
28 template<typename T>
29 vector<T>RandomArray(int n, T lo, T hi, bool no_dup=false) {
30 vector<T>ret(n);
31 if(!no_dup) for(int i=0; i<n; i++) ret[i]=RandomInt(lo,hi);
32 else {
33 set<T> st;
34 for(int i=0; i<n; i++) {
35 int r=RandomInt(lo,hi);
36 while(st.count(r)) r=RandomInt(lo,hi);
37 ret[i]=r;
38 st.insert(r);
39 }
40 }
41 return ret;
42 }
43
44 /// @brief ランダムなアルファベット文字列を返す
45 /// @param lower 小文字
46 string RandomAlphabet(int n, bool lower=true) {
47 string ret;
48 for(int i=0; i<n; i++) {
49 int idx=RandomInt(26);
50 ret.push_back(char((lower?'a':'A')+idx));
51 }
52 return ret;
53 }
54
55 /// @brief 文字列 s の要素からなるランダムな文字列を返す
56 string RandomString(int n, string s) {
57 string ret;
58 int m=s.size();
59 for(int i=0; i<n; i++) {
60 int idx=RandomInt(m);
61 ret.push_back(s[idx]);
62 }
63 return ret;
64 }
65
66 template<typename T>
67 vector<vector<T>> RandomArray2D(int h, int w, T lo, T hi) {
68 vector<vector<T>> ret(h,vector<T>(w));
69 REP(i,h) ret[i]=RandomArray(w,lo,hi);
70 return ret;
71 }
72
73 vector<string> RandomAlphabet2D(int h, int w, bool lower=true) {
74 vector<string> ret(h);
75 REP(i,h) ret[i]=RandomAlphabet(w,lower);
76 return ret;
77 }
78
79 vector<pair<int,int>> RandomTree(int n) {
80 vector<int> a=RandomArray<int>(n-2,1,n+1);
81 vector<int> d(n+1); REP(i,n-2) d[a[i]]++; for(ll i=1; i<=n; i++) d[i]++;
82 vector<pair<int,int>> ret;
83 set<int> pq;
84 for(ll i=1; i<=n; i++) if(d[i]==1) pq.insert(i);
85 REP(i,n-2) {
86 int v=(*pq.begin());
87 pq.erase(v);
88 ret.push_back(make_pair(v,a[i]));
89 d[v]--; d[a[i]]--;
90 if(d[a[i]]==1) pq.insert(a[i]);
91 else if(d[a[i]]==0) pq.erase(a[i]);
92 }
93 for(ll i=1; i<=n; i++) {
94 if(d[i]==1) {
95 for(int j=i+1; j<=n; j++) if(d[j]==1) {
96 ret.push_back(make_pair(i,j));
97 break;
98 }
99 break;
100 }
101 }
102 return ret;
103 }
104
105 vector<pair<int,int>> RandomBinaryTree(int n) {
106 vector<pair<int,int>> ret;
107 vector<ll> roots={RandomInt(1,n+1)},leaves;
108 for(ll i=1; i<=n; i++) if(i!=roots.back()) leaves.push_back(i);
109 while(!leaves.empty()) {
110 int root=GetRandomElement(roots);
111 int leaf=GetRandomElement(leaves);
112 ret.push_back(make_pair(root,leaf));
113 roots.push_back(leaf);
114 if(!leaves.empty()) {
115 int leaf=GetRandomElement(leaves);
116 ret.push_back(make_pair(root,leaf));
117 roots.push_back(leaf);
118 }
119 }
120 return ret;
121 }
122
123 vector<pair<int,int>> RandomUndirectedGraph(int n, int m, bool connected=true) {
124 vector<pair<int,int>> edges;
125 for(int i=0; i<n; i++) for(int j=i+1; j<n; j++) edges.push_back(make_pair(i+1,j+1));
126 int ed=edges.size();
127 if(!connected) {
128 vector<pair<int,int>> ret;
129 vector<int> idxs=RandomArray<int>(m,0,ed,true);
130 for(int idx:idxs) ret.push_back(edges[idx]);
131 return ret;
132 } else {
133 vector<pair<int,int>> ret;
134 while(true) {
135 ret.clear();
136 vector<int> idxs=RandomArray<int>(m,0,ed,true),parent(n);
137 vector<vector<int>> sets(n);
138 for(int i=0; i<n; i++) {
139 parent[i]=i;
140 sets[i].push_back(i);
141 }
142 for(int idx:idxs) {
143 ret.push_back(edges[idx]);
144 auto [a,b]=edges[idx];
145 a--; b--;
146 if(parent[a]!=parent[b]) {
147 if(sets[parent[a]].size()<sets[parent[b]].size()) swap(a,b);
148 for(int x:sets[parent[b]]) {
149 parent[x]=parent[a];
150 sets[parent[a]].push_back(x);
151 }
152 sets[parent[b]].clear();
153 }
154 }
155 bool ok=true;
156 for(int i=0; i<n; i++) if(parent[i]!=parent[0]) {
157 ok=false;
158 break;
159 }
160 if(ok) return ret;
161 }
162 }
163 }
164};
ランダムテストケース生成
Definition random.hpp:6
T RandomInt(T l, T r)
[l, r) の範囲からランダムな整数を返す
Definition random.hpp:13
T GetRandomElement(vector< T > &a)
配列 a からランダムな要素を取得し、削除する
Definition random.hpp:17
vector< pair< int, int > > RandomTree(int n)
Definition random.hpp:79
T RandomInt(T n)
0 以上 n 未満のランダムな整数を返す
Definition random.hpp:9
vector< pair< int, int > > RandomBinaryTree(int n)
Definition random.hpp:105
string RandomAlphabet(int n, bool lower=true)
ランダムなアルファベット文字列を返す
Definition random.hpp:46
vector< pair< int, int > > RandomUndirectedGraph(int n, int m, bool connected=true)
Definition random.hpp:123
vector< string > RandomAlphabet2D(int h, int w, bool lower=true)
Definition random.hpp:73
string RandomString(int n, string s)
文字列 s の要素からなるランダムな文字列を返す
Definition random.hpp:56
vector< vector< T > > RandomArray2D(int h, int w, T lo, T hi)
Definition random.hpp:67
vector< T > RandomArray(int n, T lo, T hi, bool no_dup=false)
長さ n の [lo, hi) の要素からなるランダムな数列を返す
Definition random.hpp:29
#define REP(i, n)
Definition template.hpp:5