zoukankan      html  css  js  c++  java
  • bzoj3230: 相似子串

    这里给出了统计有效子串以及确定其第一次出现位置的方式

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 void setIO(const string& s) {
     10     freopen((s + ".in").c_str(), "r", stdin);
     11     freopen((s + ".out").c_str(), "w", stdout);
     12 }
     13 template<typename Q> Q read(Q& x) {
     14     static char c, f;
     15     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
     16     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
     17     if(f) x = -x;
     18     return x;
     19 }
     20 template<typename Q> Q read() {
     21     static Q x; read(x); return x;
     22 }
     23 
     24 typedef long long LL;
     25 const int N = 100000 + 10, INF = ~0u >> 1;
     26 
     27 char s[N];
     28 int n, Log2[N];
     29 struct SuffixArray {
     30     int sa[N];
     31     void build_sa(const char *s, int m = 256) {
     32         static int t1[N], t2[N], c[N];
     33         int *x = t1, *y = t2;
     34         for(int i = 0; i < m; i++) c[i] = 0;
     35         for(int i = 0; i < n; i++) c[x[i] = s[i]]++;
     36         for(int i = 1; i < m; i++) c[i] += c[i-1];
     37         for(int i = 0; i < n; i++) sa[--c[x[i]]] = i;
     38         
     39         for(int k = 1; k < n; k <<= 1) {
     40             int p = 0;
     41             for(int i = n - k; i < n; i++) y[p++] = i;
     42             for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
     43             for(int i = 0; i < m; i++) c[i] = 0;
     44             for(int i = 0; i < n; i++) c[x[i]]++;
     45             for(int i = 1; i < m; i++) c[i] += c[i-1];
     46             for(int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
     47             p = 1, swap(x, y), x[sa[0]] = 0;
     48             for(int i = 1; i < n; i++) {
     49                 x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && (sa[i-1]+k < n ? y[sa[i-1]+k] : -1) == (sa[i]+k < n ? y[sa[i]+k] : -1)) ? p-1 : p++;
     50             }
     51             if(p >= n) break;
     52             m = p;
     53         }
     54     }
     55 
     56     int rank[N], height[N];
     57     
     58     void build_height(const char *s) {
     59         for(int i = 0; i < n; i++) rank[sa[i]] = i;
     60         for(int k = 0, i = 0; i < n; i++) {
     61             if(k) k--;
     62             if(!rank[i]) continue;
     63             int j = sa[rank[i]-1];
     64             while(s[i+k] == s[j+k]) k++;
     65             height[rank[i]] = k;
     66         }
     67     }
     68     
     69     LL s[N];
     70     
     71     void build_s() {
     72         s[0] = n - sa[0];
     73         for(int i = 1; i < n; i++) {
     74             s[i] = s[i-1] + n - sa[i] - height[i];
     75         }
     76     }
     77     
     78     int f[N][17];
     79     
     80     void rmq_init() {
     81         for(int i = 1; i < n; i++) f[i][0] = height[i];
     82         for(int j = 1; (1 << j) < n; j++) {
     83             for(int i = 1; i + (1 << (j-1)) < n; i++) {
     84                 f[i][j] = min(f[i][j-1], f[i + (1 << (j-1))][j-1]);
     85             }
     86         }
     87     }
     88     
     89     int rmq(int a, int b) {
     90         a = rank[a], b = rank[b];
     91         if(a > b) swap(a, b); ++a;
     92         int t = Log2[b - a + 1];
     93         return min(f[a][t], f[b - (1 << t) + 1][t]);
     94     }
     95     
     96     void kthstr(LL pos, int& a, int& b) {
     97         int x = lower_bound(s, s + n, pos) - s;
     98         a = sa[x], b = sa[x] + height[x] + pos - (x ? s[x-1] : 0);
     99     }
    100     
    101     void init(const char *s) {
    102         build_sa(s);
    103         build_height(s);
    104         build_s();
    105         rmq_init();
    106     }
    107 }A, B;
    108 
    109 int main() {
    110 #ifdef DEBUG
    111     freopen("in.txt", "r", stdin);
    112     freopen("out.txt", "w", stdout);
    113 #endif
    114     Log2[0] = -1;
    115     for(int i = 1; i < N; i++) Log2[i] = Log2[i >> 1] + 1;
    116     
    117     int m;
    118     read(n), read(m);
    119     scanf("%s", s);
    120     
    121     A.init(s);
    122     reverse(s, s + n);
    123     B.init(s);
    124     
    125     while(m--) {
    126         int a1, a2, b1, b2, t;
    127         LL l, r, ans = 0;
    128         read(l), read(r);
    129         if(l > A.s[n-1] || r > A.s[n-1]) {
    130             puts("-1");
    131             continue;
    132         }
    133         A.kthstr(l, a1, b1);
    134         A.kthstr(r, a2, b2);
    135         t = (a1 == a2) ? INF : A.rmq(a1, a2);
    136         t = min(t, min(b1 - a1, b2 - a2));
    137         ans += (LL) t * t;
    138         t = (b1 == b2) ? INF : B.rmq(n - b1, n - b2);
    139         t = min(t, min(b1 - a1, b2 - a2));
    140         ans += (LL) t * t;
    141         printf("%lld
    ", ans);
    142     }
    143     
    144     return 0;
    145 }
    View Code
  • 相关阅读:
    CF-911E.Stack Sorting(栈)
    随机算法 && CodeForces
    CF-579D."Or" Game(或运算)
    CF-242E.XOR on Segment(异或线段树)
    莫队 && 洛谷 P1494 [国家集训队]小Z的袜子
    洛谷 P4168 [Violet]蒲公英(分块)
    分块 && 洛谷 P2801 教主的魔法
    启发式合并 && U41492 树上数颜色
    使用mysqlbinlog server远程备份binlog的脚本
    mysqldump备份过程中都干了些什么
  • 原文地址:https://www.cnblogs.com/showson/p/5080732.html
Copyright © 2011-2022 走看看