zoukankan      html  css  js  c++  java
  • 【BZOJ 3879】SvT

    http://www.lydsy.com/JudgeOnline/problem.php?id=3879

    SvT的中文是后缀虚树?

    反正本蒟蒻不懂,还是$O(nlogn)$的后缀数组和单调栈维护来做,fye学姐讲了这种学法(当时并没有听懂QwQ),xiaoyimi教会了我这种做法→xiaoyimi的题解

    一开始贡献了2次TLE,以为是玄学的死循环,果断挂起对拍器拍了一晚上,然后在回家的路上才想起来TLE是因为提交的时候忘删freopen了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 500003;
    const ll p = 23333333333333333ll;
    int in() {
        int k = 0, fh = 1; char c = getchar();
        for(; c < '0' || c > '9'; c = getchar())
            if (c == '-') fh = -1;
        for(; c >= '0' && c <= '9'; c = getchar())
            k = (k << 3) + (k << 1) + c - '0';
        return k * fh;
    }
      
    int c[N], t1[N], t2[N];
      
    void st(int *x, int *y, int *sa, int n, int m) {
        for(int i = 0; i < m; ++i) c[i] = 0;
        for(int i = 0; i < n; ++i) ++c[x[y[i]]];
        for(int i = 1; i < m; ++i) c[i] += c[i - 1];
        for(int i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
    }
      
    void mkhz(int *r, int *sa, int n, int m) {
        int *x = t1, *y = t2, *t, p, i, j;
        for(i = 0; i < n; ++i) x[i] = r[i], y[i] = i;
        st(x, y, sa, n, m);
        for(p = 1, j = 1; p < n; m = p, j <<= 1) {
            for(p = 0, i = n - j; i < n; ++i) y[p++] = i;
            for(i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
            st(x, y, sa, n, m);
            for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
                x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + j] == y[sa[i - 1] + j] ? p - 1 : p++;
        }
    }
      
    void mkh(int *r, int *sa, int *rank, int *h, int n) {
        int k = 0, j, i;
        for(i = 0; i < n; ++i) rank[sa[i]] = i;
        for(i = 1; i < n; h[rank[i++]] = k)
            for(k ? --k : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; ++k);
    }
      
    char s[N];
    int n, m, sa[N], rank[N], r[N], h[N], f[N][20], Log_2[N], a[N];
      
    int get_min(int l, int r) {
        int len = Log_2[r - l];
        return min(f[l][len], f[r - (1 << len)][len]);
    }
      
    int get_LCP(int l, int r) {
        l = rank[l]; r = rank[r];
        if (l > r) swap(l, r);
        return get_min(l, r);
    }
      
    bool cmp(int x, int y) {
        return rank[x] < rank[y];
    }
      
    int sta[N], top, bef[N], size[N];
      
    void sub(ll &x, ll y) {
        x -= y; if (x < 0) x += p;
    }
      
    void add(ll &x, ll y) {
        x += y; if (x > p) x -= p;
    }
      
    int main() {
        n = in(); m = in();
        scanf("%s", s + 1);
        r[0] = 0;
        for(int i = 1; i <= n; ++i) r[i] = s[i] - 'a' + 1;
        mkhz(r, sa, n + 1, 27);
        mkh(r, sa, rank, h, n + 1);
          
        for(int i = 0; i < n; ++i) f[i][0] = h[i + 1];
        for(int j = 1; j < 20; ++j)
            for(int i = 0; i < n; ++i) {
                if (i + (1 << (j - 1)) >= n) break;
                f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
            }
          
        int tmp = 0;
        for(int i = 1; i <= n; ++i) {
            if ((1 << (tmp + 1)) < i) ++tmp;
            Log_2[i] = tmp;
        }
          
        int tot; ll sum, ans = 0;
        while (m--) {
            tot = in();
            for(int i = 1; i <= tot; ++i) a[i] = in();
            sort(a + 1, a + tot + 1, cmp);
            tot = unique(a + 1, a + tot + 1) - a;
            --tot;
            for(int i = 1; i < tot; ++i) bef[i] = get_LCP(a[i], a[i + 1]);
              
            top = 0; sum = 0; ans = 0;
            for(int i = 1; i < tot; ++i) {
                size[i] = 1;
                while (top && bef[i] < bef[sta[top]]) {
                    sub(sum, 1ll * bef[sta[top]] * size[sta[top]] % p);
                    size[i] += size[sta[top]];
                    --top;
                }
                sta[++top] = i;
                add(sum, 1ll * bef[i] * size[i] % p);
                add(ans, sum);
            }
            printf("%lld
    ", ans);
        }
          
        return 0;
    }
    

    再一次被自己的智商感动QAQ

  • 相关阅读:
    appium python api(转)
    make clean 与 make distclean 的区别
    实参相依查找[条款25]----《C++必知必会》
    成员函数查找[条款24]---《C++必知必会》
    C++匿名名字空间
    程序界面多语言切换功能如何实现
    C 语言中 define 的全部使用方法总结
    #if defined(__cplusplus)
    伯乐在线
    jsp手动分页
  • 原文地址:https://www.cnblogs.com/abclzr/p/5774447.html
Copyright © 2011-2022 走看看