zoukankan      html  css  js  c++  java
  • K-th occurrence

    K-th occurrence

    Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
    Total Submission(s): 461    Accepted Submission(s): 125


    Problem Description
    You are given a string S consisting of only lowercase english letters and some queries.

    For each query (l,r,k), please output the starting position of the k-th occurence of the substring SlSl+1...Sr in S.
     
    Input
    The first line contains an integer T(1T20), denoting the number of test cases.

    The first line of each test case contains two integer N(1N105),Q(1Q105), denoting the length of S and the number of queries.

    The second line of each test case contains a string S(|S|=N) consisting of only lowercase english letters.

    Then Q lines follow, each line contains three integer l,r(1lrN) and k(1kN), denoting a query.

    There are at most 5 testcases which N is greater than 103.
     
    Output
    For each query, output the starting position of the k-th occurence of the given substring.

    If such position don't exists, output 1 instead.
     
    Sample Input
    2 12 6 aaabaabaaaab 3 3 4 2 3 2 7 8 3 3 4 2 1 4 2 8 12 1 1 1 a 1 1 1
     
    Sample Output
    5 2 -1 6 9 8 1
    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int maxn = (1e5 + 10) * 100;
    int M = 30;
    int T, n, q, len, tot;
    char s[maxn];
    int sa[maxn], height[maxn];
    int rk[maxn], tp[maxn];
    int str[maxn], ton[maxn], root[maxn];
    int f[300600][36];
    struct tree {
        int l, r, val;
    } c[maxn];
    
    inline void rsort() {
        for (register int i = 0; i <= M; ++i)ton[i] = 0;
        for (register int i = 1; i <= len; ++i)ton[rk[i]]++;
        for (register int i = 1; i <= M; ++i)ton[i] = ton[i] + ton[i - 1];
        for (register int i = len; i >= 1; --i)sa[ton[rk[tp[i]]]--] = tp[i];
    }
    
    inline void get_height() {
        len++;
        for (register int i = 1; i <= len; ++i)rk[i] = str[i], tp[i] = i;
        rsort();
        for (register int w = 1, p = 0; p < len && w <= len; M = p, w *= 2) {
            p = 0;
            for (register int i = len - w + 1; i <= len; ++i)tp[++p] = i;
            for (register int i = 1; i <= len; ++i) {
                if (sa[i] > w) {
                    tp[++p] = sa[i] - w;
                }
            }
            rsort();
            swap(rk, tp);
            rk[sa[1]] = p = 1;
            for (register int i = 2; i <= len; ++i) {
                rk[sa[i]] = (tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i - 1] + w] == tp[sa[i] + w]) ? p : ++p;
            }
            if (p >= len)break;
            //printf("%d
    ",p);
        }
    //    for (register int i = 1; i <= n; ++i) {
    //        printf("sa[ %d ] = %d
    ", i, sa[i]);
    //    }
        int cur_len = len;
        cur_len--;
        int k = 0;
        for (register int i = 1; i <= len; ++i)rk[sa[i]] = i;
    //    for(register int i=1;i<=len;++i){
    //        printf("rk[ %d ] = %d
    ", i, rk[i]);
    //    }
        for (register int i = 1; i <= cur_len; ++i) {
            if (k)--k;
            else k = 0;
            int j = sa[rk[i] - 1];
            while (str[i + k] == str[j + k])k++;
            height[rk[i]] = k;
        }
    }
    
    inline void init() {
        for (register int i = 1; i <= len; ++i)f[i][0] = height[i];
        for (register int j = 1; j <= 23; ++j) {
            for (register int i = 1; i + (1 << j) - 1 <= len; ++i) {
                f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    
    inline int query(int l, int r) {
        int cur = log2(r - l + 1.0);
        return min(f[l][cur], f[r - (1 << cur) + 1][cur]);
    }
    
    inline int update(int pre, int l, int r, int pos) {
        int nx = ++tot;
        c[nx] = c[pre];
        c[nx].val++;
        if (l == r)return nx;
        int mid = l + r >> 1;
        if (pos <= mid) {
            c[nx].l = update(c[pre].l, l, mid, pos);
        } else {
            c[nx].r = update(c[pre].r, mid + 1, r, pos);
        }
        return nx;
    }
    
    inline int query(int pl, int pr, int l, int r, int val) {
        if (l == r)return l;
        int mid = l + r >> 1;
        if (c[c[pr].l].val - c[c[pl].l].val >= val) {
            return query(c[pl].l, c[pr].l, l, mid, val);
        } else {
            return query(c[pl].r, c[pr].r, mid + 1, r, val - (c[c[pr].l].val - c[c[pl].l].val));
        }
    }
    
    int main() {
        //freopen("1.txt", "r", stdin);
        scanf("%d", &T);
        while (T--) {
            tot = 0;
            scanf("%d%d", &n, &q);
            scanf("%s", s + 1);
            len = strlen(s + 1);
            for (register int i = 0; i <= len + 1; ++i)root[i] = 0;
            M = 30;
            //printf("debug len = %d
    ",len);
            for (register int i = 1; i <= len; ++i)str[i] = s[i] - 'a' + 1;
            str[len + 1] = 0;
            get_height();
            init();
            for (register int i = 1; i <= len + 1; ++i) {
                root[i] = update(root[i - 1], 1, n, sa[i]);
                //printf("debug root[%d] = %d
    ",i,root[i]);
            }
            int l, r, k;
            while (q--) {
                scanf("%d%d%d", &l, &r, &k);
                int siz = r - l + 1;
                //printf("debug rk[l] = %d
    ",rk[l]);
                l = rk[l];
    
                int L = 1, R = l, ans_l, ans_r;
                while (L <= R) {
                    int mid = L + R >> 1, cur;
                    cur = 100000;
                    if (mid + 1 <= l) cur = query(mid + 1, l);
                    if (cur >= siz) {
                        ans_l = mid;
                        R = mid - 1;
                    } else {
                        L = mid + 1;
                    }
    //                cur = query(mid, l);
    //                if (cur >= siz) {
    //                    ans_l = mid;
    //                    R = mid - 1;
    //                } else {
    //                    L = mid + 1;
    //                }
                }
                //printf("debug ans_l = %d
    ",ans_l);
                L = l, R = len;
                while (L <= R) {
                    int mid = L + R >> 1, cur;
                    cur = 100000;
                    if (l + 1 <= mid) cur = query(l + 1, mid);
                    if (cur >= siz) {
                        ans_r = mid;
                        L = mid + 1;
                    } else {
                        R = mid - 1;
                    }
    //                cur = query(l, mid);
    //                if (cur >= siz) {
    //                    ans_l = mid;
    //                    R = mid - 1;
    //                } else {
    //                    L = mid + 1;
    //                }
                }
    //            int pos = rk[l - 1];
    //            int L = 1, R = pos, LL = pos, RR = pos;
    //            while (L < R) {
    //                int mid = (L + R) / 2;
    //                if (query(mid, pos) >= r - l + 1)
    //                    R = mid;
    //                else
    //                    L = mid + 1;
    //            }
    //            if (query(L, pos) >= r - l + 1)
    //                LL = L - 1;
    //            if (pos < n - 1) {
    //                pos++;
    //                L = pos, R = n - 1;
    //                while (L < R) {
    //                    int mid = (L + R) / 2;
    //                    if (query(pos, mid) >= r - l + 1)
    //                        L = mid + 1;
    //                    else
    //                        R = mid;
    //                }
    //                if (query(pos, L) < r - l + 1)
    //                    L--;
    //                if (L >= pos && query(pos, L) >= r - l + 1)
    //                    RR = L;
    //            }
                //printf("debug ans_l = %d ans_r = %d
    ",ans_l,ans_r);
                if (ans_r - ans_l + 1 < k) {
                    puts("-1");
                } else {
                    printf("%d
    ", query(root[ans_l - 1], root[ans_r], 1, n, k));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    如何只通过Sandboxed Solution启动一个定时执行的操作
    创建与SharePoint 2010风格一致的下拉菜单 (续) 整合Feature Custom Action框架
    创建与SharePoint 2010风格一致的下拉菜单
    《SharePoint 2010 应用程序开发指南》第二章预览
    SharePoint 2013 App 开发 (1) 什么是SharePoint App?
    使用Jscex增强SharePoint 2010 JavaScript Client Object Model (JSOM)
    搜索范围的管理
    SharePoint 2010 服务应用程序(Service Application)架构(1)
    SharePoint 2010 服务应用程序(Service Application)架构(2)
    SharePoint 2013 App 开发 (2) 建立开发环境
  • 原文地址:https://www.cnblogs.com/czy-power/p/11404138.html
Copyright © 2011-2022 走看看