题目链接:点击打开链接
#include <cstdio>
#include <cstring>
typedef unsigned long long ll;
const int key = (int)(1e9) + 7;
const int N = 150010;
char b[N], a[N + N];
ll xp[N], h[N + N];
int len;
void get() {
char ch;
while ((ch = getchar()) < '0' || ch > '9');
int t = 0;
b[t++] = ch;
while ((ch = getchar()) >= '0' && ch <= '9')
b[t++] = ch;
b[t] = '\0';
}
void make(ll* h, char* s, int len) {
h[len] = 0;
for (int i = len - 1; i >= 0; --i)
h[i] = h[i + 1] * key + (s[i] - '0' + 1);
}
ll H(ll *h, int st, int len) {
return h[st] - h[st + len] * xp[len];
}
bool cmp(ll* h1, char* a1, int s1, ll* h2, char* a2, int s2) {
if (a1[s1] != a2[s2])
return a1[s1] > a2[s2];
else if (H(h1, s1, len) == H(h2, s2, len))
return true;
int l = -1, r = len, mid;
while (r - l > 1) {
mid = (l + r) >> 1;
if (H(h1, s1, mid) != H(h2, s2, mid))
r = mid;
else
l = mid;
}
return a1[s1 + r - 1] > a2[s2 + r - 1];
}
int main() {
xp[0] = 1;
for (int i = 1; i < N; ++i)
xp[i] = xp[i - 1] * key;
int n, k, ansi, ansj, cc, pos;
while(~scanf("%d%d", &n, &k)) {
k %= n;
//scanf("%s", b);
get();
if (k != 0 && n % k == 0)
cc = k;
else if (k == 0)
cc = n;
else
cc = 1;
len = n / cc;
for (int i = 0; i < cc; ++i) {
pos = i;
for (int j = 0; j < len; ++j) {
a[i * len * 2 + j] = a[i * len * 2 + j + len] = b[pos];
pos = pos + k;
if (pos >= n)
pos -= n;
}
make(h + i * len * 2, a + i * len * 2, len * 2);
}
ansi = 0;
ansj = 0;
for (int i = 0; i < cc; ++i)
for (int j = 0; j < len; ++j)
if (cmp(h + i * len * 2, a + i * len * 2, j, h + ansi * len * 2, a + ansi * len * 2, ansj)) {
ansi = i;
ansj = j;
}
for (int j = 0; j < n; ++j)
putchar(a[ansi * len * 2 + (ansj++) % len]);
putchar('\n');
}
return 0;
}SGU 232 Infinite Fraction Hash
原文:http://blog.csdn.net/qq574857122/article/details/39373965