首页 > 代码库 > uva 12338 - Anti-Rhyme Pairs(后缀数组+RMQ)

uva 12338 - Anti-Rhyme Pairs(后缀数组+RMQ)

题目链接:uva 12338 - Anti-Rhyme Pairs

题目大意:给定若干个字符串,每次询问两个字符串的最长公共前缀。

解题思路:本来应该将每个字符串连接起来做后缀数组,但其实可以直接把一个字符串看成是一个字符,然后排序了就对应是SA数组,然后处理height即可。然后根据后缀数组的性质,字符串i和j的最长公共前缀长度即为rank[i]+1~rank[j]之间height的最小值。特判i=j的情况。

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;
typedef pair<string, int> pii;
const int maxn = 1e5+5;

int Rank[maxn];
int dp[maxn][20];
vector<pii> g;
vector<int> height;

void rmq_init(const vector<int>& A) {
    int n = A.size();
    for (int i = 0; i < n; i++)
        dp[i][0] = A[i];

    for (int j = 1; (1<<j) <= n; j++) {
        for (int i = 0; i + (1<<j) - 1 < n; i++)
            dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
    }
}

int rmq_query (int l, int r) {

    if (l == r)
        return g[l].first.length();

    if (l > r)
        swap(l, r);

    l++;

    int k = 0;
    while ((1<<(k+1)) <= r - l + 1)
        k++;
    return min(dp[l][k], dp[r - (1<<k) + 1][k]);
}

void solve () {
    sort(g.begin(), g.end());

    for (int i = 0; i < g.size(); i++)
        Rank[g[i].second] = i;

    height.clear();
    height.push_back(0);
    for (int i = 1; i < g.size(); i++) {
        int n = min(g[i].first.length(), g[i-1].first.length());;
        int j;
        for (j = 0; j < n; j++)
            if (g[i].first[j] != g[i-1].first[j])
                break;
        height.push_back(j);
    }
    rmq_init(height);
}

int main () {
    int cas, n, l, r;
    string s;
    cin >> cas;
    for (int kcas = 1; kcas <= cas; kcas++) {
        cin >> n;
        g.clear();

        for (int i = 0; i < n; i++) {
            cin >> s;
            g.push_back(make_pair(s, i));
        }
        solve();

        cout << "Case " << kcas << ":" << endl;
        cin >> n;
        while (n--) {
            cin >> l >> r;
            cout << rmq_query(Rank[l-1], Rank[r-1]) << endl;
        }
    }
    return 0;
}

uva 12338 - Anti-Rhyme Pairs(后缀数组+RMQ)