uva 719 - Glass Beads(最小表示法 | 后缀自动机)

题目链接:uva 719 - Glass Beads

题目大意:给定一个字符串,求最小表示法。

解题思路:最小表示法 | 后缀自动机

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const  int maxn = 1e4+5;

char s[maxn];

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%s", s);
        int n = strlen(s), p = 0, q = 1;

        while (p < n && q < n) {
            int i;
            for (i = 0; i < n; i++) {
                if (s[(p+i)%n] != s[(q+i)%n])
                    break;
            }

            if (s[(p+i)%n] > s[(q+i)%n])
                p = p + i + 1;
            else
                q = q + i + 1;

            if (p == q)
                q++;
        }
        printf("%d\n", min(p, q) + 1);
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 20005;
const int SIGMA_SIZE = 26;

struct SAM {
	int sz, last;
	int g[maxn<<1][SIGMA_SIZE], pre[maxn<<1], step[maxn<<1];

	void newNode(int s) {
		step[++sz] = s;
		pre[sz] = 0;
		memset(g[sz], 0, sizeof(g[sz]));
	}

	int idx(char ch) { return ch - 'a'; }

	void init () {
		sz = 0, last = 1;
		newNode(0);
	}

	void insert(char ch) {
		newNode(step[last]+1);
		int c = idx(ch);
		int p = last, np = sz;

		while (p && !g[p][c]) {
			g[p][c] = np;
			p = pre[p];
		}

		if (p) {
			int q = g[p][c];
			if (step[q] == step[p] + 1) {
				pre[np] = q;
			} else {
				newNode(step[p] + 1);
				int nq = sz;
				for (int j = 0; j < SIGMA_SIZE; j++)
					g[nq][j] = g[q][j];
				pre[nq] = pre[q];
				pre[np] = pre[q] = nq;

				while (p && g[p][c] == q) {
					g[p][c] = nq;
					p = pre[p];
				}
			}
		} else
			pre[np] = 1;

		last = np;
	}

	int solve(int n) {
		int u = 1;
		while (n--) {
			for (int i = 0; i < SIGMA_SIZE; i++) if (g[u][i]) {
				u = g[u][i];
				break;
			}
		}
		return step[u];
	}
}sam;

char str[maxn];

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		scanf("%s", str);
		int n = strlen(str);
		sam.init();
		for (int k = 0; k < 2; k++) {
			for (int i = 0; i < n; i++)
				sam.insert(str[i]);
		}
		int k = sam.solve(n);
		printf("%d\n", k - n + 1);
	}
	return 0;
}



你可能感兴趣的:(uva 719 - Glass Beads(最小表示法 | 后缀自动机))