题意很清楚:可以用后缀树组来做,也能直接用最小表示
输入:scanf("%d", n);
最小表示:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <string>
using namespace std;
const int MAXN = 200002;
int s[MAXN], n;
int mini(int li, int len)
{
int i, j, k;
for (i = li, k = 0, j = li + 1; i < len && j < len && k < len;)
{
int t = s[(i + k) % len] - s[(j + k) % len];
if (!t)
{
k++;
}
else
{
if (t > 0)
{
i = i + k + 1;
}
else
{
j = j + k + 1;
}
if (i == j)
{
j++;
}
k = 0;
}
}
return min(i, j);
}
void input()
{
int mx = -1;
scanf("%d", &n);
for (int i = n - 1; i >= 0; i--)
{
scanf("%d", &s[i]);
}
int pos = mini(2, n);
for (int i = pos; i < n; i++)
{
printf("%d\n", s[i]);
}
int p = mini(1, pos);
for (int i = p; i < pos; i++)
{
printf("%d\n", s[i]);
}
for (int i = 0; i < p; i++)
{
printf("%d\n", s[i]);
}
}
int main()
{
input();
return 0;
}
后缀数组:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <string>
using namespace std;
const int MAXN = 2000020;
int s[MAXN], sa[MAXN], t[MAXN], t2[MAXN], c[MAXN], ranks[MAXN], n;
struct Node
{
int val, id;
}node[MAXN];
void build_sa(int n, int m)
{
int i, *x = t, *y = t2;
for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[i] = s[i]]++;
for (i = 1; i < m; i++) c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for (int k = 1; k <= n; k <<= 1)
{
int p = 0;
for (i = n - k; i < n; i++) y[p++] = i;
for (i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
//基数排序第一关键字
for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[y[i]]]++;
for (i = 0; i < m; i++) c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[sa[0]] = 0;
for (i = 1; i < n; i++)
x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
if (p >= n) break;
m = p;
}
for (i = 0; i < n; i++) ranks[sa[i]] = i;
}
int mini(int len)
{
int i, j, k;
for (i = 1, k = 0, j = 2; i < len && j < len && k < len;)
{
int t = s[(i + k) % len] - s[(j + k) % len];
if (!t)
{
k++;
}
else
{
if (t > 0)
{
i = i + k + 1;
}
else
{
j = j + k + 1;
}
if (i == j)
{
j++;
}
k = 0;
}
}
return min(i, j);
}
bool cmp(Node a, Node b)
{
if (a.val == b.val)
{
return a.id < b.id;
}
return a.val < b.val;
}
void input()
{
int mx = -1;
scanf("%d", &n);
{
for (int i = n - 1; i >= 0; i--)
{
scanf("%d", &node[i].val);
node[i].id = i;
}
sort(node, node + n, cmp);
for (int i = 0; i < n; i++)
{
if (i && node[i].val == node[i - 1].val)
{
s[node[i].id] = s[node[i - 1].id];
continue;
}
s[node[i].id] = i + 1;
}
s[n] = 0;
build_sa(n + 1, n + 10);
int pos = 0;
for (int i = 1; i <= n; i++)
{
if (sa[i] > 1)
{
pos = sa[i];
break;
}
}
for (int i = pos; i < n; i++)
{
cout << node[s[i] - 1].val << endl;
}
int p = mini(pos);
for (int i = p; i < pos; i++)
{
cout << node[s[i] - 1].val << endl;
}
for (int i = 0; i < p; i++)
{
cout << node[s[i] - 1].val << endl;
}
}
}
int main()
{
input();
return 0;
}