-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen.cpp
140 lines (126 loc) · 3.18 KB
/
gen.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define accuracy chrono::steady_clock::now().time_since_epoch().count()
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int N = 1e6 + 4;
int32_t permutation[N];
mt19937 rng(accuracy);
int rand(int l, int r)
{
uniform_int_distribution<int> ludo(l, r);
return ludo(rng);
}
const int inf = 1LL << 31;
using pii = pair<int, int>;
namespace generator
{
string gen_string(int len = 0, bool upperCase = false)
{
assert(len >= 0 && len <= 5e6);
string str(len, (upperCase ? 'A' : 'a'));
for (char &ch : str)
{
if (rand(0, 1) == 0)
{
ch += 5;
}
else
{
ch += 22;
}
}
return str;
}
vector<int> gen_array(int len = 0, int minRange = 0, int maxRange = inf)
{
assert(len >= 0 and len <= 5e6);
vector<int> a(len);
for (int &x : a)
x = rand(minRange, maxRange);
return a;
}
vector<pair<int, int>> gen_tree(int n = 0)
{
assert(n >= 0);
vector<pii> res(n ? n - 1 : 0);
// if you like to have bamboo like tree or star like tree uncomment below 8 lines
/*if (rng() % 5 == 0) { // bamboo like tree
for (int i = 1; i < n; ++i) res[i-1] = {i, i + 1};
return res;
}
if (rng() % 7 == 0) { // star tree
for (int i = 2; i <= n; ++i) res[i-2] = {1, i};
return res;
}*/
iota(permutation, permutation + 1 + n, 0);
shuffle(permutation + 1, permutation + 1 + n, rng);
for (int i = 2; i <= n; ++i)
{
int u = i, v = rand(1, i - 1);
u = permutation[u], v = permutation[v];
res[i - 2] = minmax(u, v); // u < v, just for convenience while debugging
}
shuffle(res.begin(), res.end(), rng);
return res;
}
vector<pair<int, int>> simple_graph(int n = 0, int m = 0)
{
assert(n > 0 && m >= n);
int max_edges = n * (n - 1) / 2;
assert(m <= max_edges);
vector<pii> res = gen_tree(n);
set<pii> edge(res.begin(), res.end());
for (int i = n; i <= m; ++i)
{
while (true)
{
int u = rand(1, n), v = rand(1, n);
if (u == v)
continue;
auto it = edge.insert(minmax(u, v));
if (it.second)
break;
}
}
res.assign(edge.begin(), edge.end());
return res;
}
}
using namespace generator;
template <typename T = int>
ostream &operator<<(ostream &other, const vector<T> &v)
{
for (const T &x : v)
other << x << ' ';
other << '\n';
return other;
}
ostream &operator<<(ostream &other, const vector<pair<int, int>> &v)
{
for (const auto &x : v)
other << x.first << ' ' << x.second << '\n';
return other;
}
// comment the just below line if test cases required
// #define SINGLE_TEST
const int max_tests = 10000;
// complete this function according to the requirements
void generate_test()
{
int n = rand(1, 10000);
cout << n << '\n';
cout << gen_string(n, false) << '\n';
}
signed main()
{
srand(accuracy);
int t = 1;
#ifndef SINGLE_TEST
t = rand(1, max_tests), cout << t << '\n';
#endif
while (t--)
{
generate_test();
}
}