1
+ #include < bits/stdc++.h>
2
+
3
+ using namespace std ;
4
+
5
+ #define print_op (...) ostream& operator <<(ostream& out, const __VA_ARGS__& u)
6
+ template <typename A, typename B> print_op (pair<A, B>) { return out << " (" << u.first << " , " << u.second << " )" ; }
7
+ template <typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> print_op (T_container) { out << " {" ; string sep; for (const T &x : u) out << sep << x, sep = " , " ; return out << " }" ; }
8
+ template <typename T> void dbg_out (string s, T x) {cerr << " \033 [1;35m" << s << " \033 [0;32m = \033 [33m" << x << " \033 [0m\n " ;}
9
+ template <typename T, typename ... Args> void dbg_out (string s, T x, Args... args) {for (int i=0 , b=0 ; i<(int )s.size (); i++) if (s[i] == ' (' || s[i] == ' {' ) b++; else
10
+ if (s[i] == ' )' || s[i] == ' }' ) b--; else if (s[i] == ' ,' && b == 0 ) {cerr << " \033 [1;35m" << s.substr (0 , i) << " \033 [0;32m = \033 [33m" << x << " \033 [31m | " ; dbg_out (s.substr (s.find_first_not_of (' ' , i + 1 )), args...); break ;}}
11
+ #ifdef LOCAL
12
+ #define dbg (...) dbg_out(#__VA_ARGS__, __VA_ARGS__)
13
+ #else
14
+ #define dbg (...)
15
+ #endif
16
+
17
+ #define ar array
18
+ #define ll long long
19
+ #define ld long double
20
+ #define sz (x ) ((int )x.size())
21
+ #define rep (i, a, b ) for (int i = (int )(a); i < (int )(b); i++)
22
+ #define all (a ) (a).begin(), (a).end()
23
+
24
+ const int MAX_N = 1e5 + 5 ;
25
+ const int MAX_L = 20 ;
26
+ const int MAX_C = 26 ;
27
+ const ll MOD = 1e9 + 7 ;
28
+ const ll INF = 1e9 ;
29
+ const ld EPS = 1e-9 ;
30
+
31
+ using ull = unsigned long long ;
32
+
33
+ struct PolyHash {
34
+ static const ull MOD = (1ULL << 61 ) - 1 ;
35
+ static int BASE;
36
+
37
+ static inline ull add (ull a, ull b) {
38
+ a += b;
39
+ if (a >= MOD)
40
+ a -= MOD;
41
+ return a;
42
+ }
43
+
44
+ static inline ull sub (ull a, ull b) {
45
+ a -= b;
46
+ if (a >= MOD)
47
+ a += MOD;
48
+ return a;
49
+ }
50
+
51
+ static inline ull mul (ull a, ull b) {
52
+ ull l1 = (uint32_t ) a, h1 = a >> 32 , l2 = (uint32_t ) b, h2 = b >> 32 ;
53
+ ull l = l1 * l2, m = l1 * h2 + l2 * h1, h = h1 * h2;
54
+ ull ret = (l & MOD) + (l >> 61 ) + (h << 3 ) + (m >> 29 ) + (m << 35 >> 3 ) + 1 ;
55
+ ret = (ret & MOD) + (ret >> 61 );
56
+ ret = (ret & MOD) + (ret >> 61 );
57
+ return ret - 1 ;
58
+ }
59
+
60
+ vector<ull> power, pref;
61
+
62
+ PolyHash (const string &s) : pref(s.length() + 1 ) {
63
+ while ((int ) power.size () <= (int ) s.length ())
64
+ power.push_back (power.empty () ? 1 : mul (power.back (), BASE));
65
+
66
+ for (int i = 0 ; i < (int ) s.length (); i++)
67
+ pref[i + 1 ] = add (mul (pref[i], BASE), s[i]);
68
+ }
69
+
70
+ ull operator () (int pos, int len) const {
71
+ return sub (pref[pos + len], mul (pref[pos], power[len]));
72
+ }
73
+ };
74
+
75
+ int gen () {
76
+ auto seed = chrono::high_resolution_clock::now ().time_since_epoch ().count ();
77
+ mt19937 gen (seed ^ ull (new ull));
78
+ uniform_int_distribution<int > dist (258 , 2e9 - 1 );
79
+ int base = dist (gen);
80
+ return base % 2 == 0 ? base - 1 : base;
81
+ }
82
+
83
+ int PolyHash::BASE = gen();
84
+
85
+ void solve (int tc = 0 ) {
86
+ string s; cin >> s;
87
+ int n = sz (s);
88
+ s += s;
89
+ auto hs = PolyHash (s);
90
+
91
+ // compare 2 substrings s[a...a+n-1] and s[b...b+n-1] in log(n) time complexity
92
+ auto cmp = [&](const int &a, const int &b) -> bool {
93
+ if (s[a] != s[b]) return s[a] < s[b];
94
+ if (hs (a, n) == hs (b, n)) return false ;
95
+ int lo = 1 , hi = n;
96
+ while (lo + 1 < hi) {
97
+ int mid = (lo + hi) / 2 ;
98
+ if (hs (a, mid) == hs (b, mid)) lo = mid;
99
+ else hi = mid;
100
+ }
101
+ return s[a + hi - 1 ] < s[b + hi - 1 ];
102
+ };
103
+
104
+ int mn = 0 ;
105
+ for (int i = 1 ; i < n; i++) {
106
+ if (cmp (i, mn)) {
107
+ mn = i;
108
+ }
109
+ }
110
+ cout << s.substr (mn, n) << " \n " ;
111
+ }
112
+
113
+ signed main () {
114
+ ios_base::sync_with_stdio (false ); cin.tie (NULL );
115
+ int tc = 1 ;
116
+ // cin >> tc;
117
+ for (int t = 1 ; t <= tc; t++) {
118
+ // cout << "Case #" << t << ": ";
119
+ solve (t);
120
+ }
121
+ }
0 commit comments