• 【POJ】3415 Common Substrings


    后缀数组可解。使用单调栈优化。

      1 /* 3415 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <algorithm>
     12 #include <cstdio>
     13 #include <cmath>
     14 #include <ctime>
     15 #include <cstring>
     16 #include <climits>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <functional>
     20 #include <iterator>
     21 #include <iomanip>
     22 using namespace std;
     23 //#pragma comment(linker,"/STACK:102400000,1024000")
     24 
     25 #define sti                set<int>
     26 #define stpii            set<pair<int, int> >
     27 #define mpii            map<int,int>
     28 #define vi                vector<int>
     29 #define pii                pair<int,int>
     30 #define vpii            vector<pair<int,int> >
     31 #define rep(i, a, n)     for (int i=a;i<n;++i)
     32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     33 #define clr                clear
     34 #define pb                 push_back
     35 #define mp                 make_pair
     36 #define fir                first
     37 #define sec                second
     38 #define all(x)             (x).begin(),(x).end()
     39 #define SZ(x)             ((int)(x).size())
     40 #define lson            l, mid, rt<<1
     41 #define rson            mid+1, r, rt<<1|1
     42 
     43 const int maxl = 1e5+5;
     44 const int maxn = maxl * 2;
     45 char as[maxl], bs[maxl];
     46 int a[maxn];
     47 int rank[maxn], height[maxn], sa[maxn];
     48 int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
     49 int S[maxn][2];
     50 int K;
     51 
     52 bool cmp(int *r, int a, int b, int l) {
     53     return r[a]==r[b] && r[a+l]==r[b+l];
     54 }
     55 
     56 void da(int *r, int *sa, int n, int m) {
     57     int i, j, *x=wa, *y=wb, *t, p;
     58     
     59     for (i=0; i<m; ++i) wc[i] = 0;
     60     for (i=0; i<n; ++i) wc[x[i]=r[i]]++;
     61     for (i=1; i<m; ++i) wc[i] += wc[i-1];
     62     for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i;
     63     for (j=1,p=1; p<n; j*=2, m=p) {
     64         for (p=0,i=n-j; i<n; ++i) y[p++] = i;
     65         for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
     66         for (i=0; i<n; ++i) wv[i] = x[y[i]];
     67         for (i=0; i<m; ++i) wc[i] = 0;
     68         for (i=0; i<n; ++i) wc[wv[i]]++;
     69         for (i=1; i<m; ++i) wc[i] += wc[i-1];
     70         for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i];
     71         for (t=x,x=y,y=t, x[sa[0]]=0, p=1, i=1; i<n; ++i)
     72             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++;
     73     }
     74 }
     75 
     76 void calheight(int *r, int *sa, int n) {
     77     int i, j, k = 0;
     78     
     79     for (i=1; i<=n; ++i) rank[sa[i]] = i;
     80     for (i=0; i<n; height[rank[i++]]=k)
     81     for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k);
     82 }
     83 
     84 void printSa(int n) {
     85     for (int i=1; i<=n; ++i)
     86         printf("%d ", sa[i]);
     87     putchar('
    ');
     88 }
     89 
     90 void printHeight(int n) {
     91     for (int i=1; i<=n; ++i)
     92         printf("%d ", height[i]);
     93     putchar('
    ');
     94 }
     95 
     96 void solve() {
     97     int n = 0, nn;
     98     
     99     for (int i=0; ; ++i) {
    100         if (as[i] == '') {
    101             nn = i;
    102             break;
    103         }
    104         a[n++] = as[i];
    105     }
    106     a[n++] = 1;
    107     for (int i=0; ; ++i) {
    108         if (bs[i] == '') {
    109             break;
    110         }
    111         a[n++] = bs[i];
    112     }
    113     a[n] = 0;
    114     
    115     da(a, sa, n+1, 130);
    116     calheight(a, sa, n);
    117     
    118     int top;
    119     __int64 tot, ans = 0;
    120     
    121     // handle as with bs
    122     top = 0;
    123     tot = 0;
    124     rep(i, 1, n+1) {
    125         if (height[i] < K) {
    126             top = 0;
    127             tot = 0;
    128         } else {
    129             int cnt = 0;
    130             if (sa[i-1] < nn) {
    131                 ++cnt;
    132                 tot += height[i] - K + 1;
    133             }
    134             while (top && height[i]<=S[top-1][0]) {
    135                 --top;
    136                 tot -= 1LL * S[top][1] * (S[top][0] - height[i]);
    137                 cnt += S[top][1];
    138             }
    139             S[top][0] = height[i];
    140             S[top][1] = cnt;
    141             ++top;
    142             if (sa[i] > nn)
    143                 ans += tot;
    144         }
    145     }
    146     
    147     
    148     tot = 0;
    149     top = 0;
    150     rep(i, 1, n+1) {
    151         if (height[i] < K) {
    152             tot = 0;
    153             top = 0;
    154         } else {
    155             int cnt = 0;
    156             if (sa[i-1] > nn) {
    157                 ++cnt;
    158                 tot += height[i] - K + 1;
    159             }
    160             while (top && height[i]<=S[top-1][0]) {
    161                 --top;
    162                 tot -= 1LL * S[top][1] * (S[top][0] - height[i]);
    163                 cnt += S[top][1];
    164             }
    165             S[top][0] = height[i];
    166             S[top][1] = cnt;
    167             ++top;
    168             if (sa[i] < nn)
    169                 ans += tot;
    170         }
    171     }
    172     
    173     printf("%I64d
    ", ans);
    174 }
    175 
    176 int main() {
    177     ios::sync_with_stdio(false);
    178     #ifndef ONLINE_JUDGE
    179         freopen("data.in", "r", stdin);
    180         freopen("data.out", "w", stdout);
    181     #endif
    182     
    183     while (scanf("%d", &K)!=EOF && K) {
    184         scanf("%s%s", as, bs);
    185         solve();
    186     }
    187     
    188     #ifndef ONLINE_JUDGE
    189         printf("time = %d.
    ", (int)clock());
    190     #endif
    191     
    192     return 0;
    193 }

     数据发生器。

     1 from random import randint, shuffle
     2 import shutil
     3 import string
     4 
     5 
     6 def GenDataIn():
     7     with open("data.in", "w") as fout:
     8         t = 20
     9         bound = 10**2
    10         lc = list(string.lowercase)
    11         for tt in xrange(t):
    12             k = randint(1, 10)
    13             fout.write("%d
    " % (k))
    14             length = randint(100, 500)
    15             line = ""
    16             for i in xrange(length):
    17                 idx = randint(0, 25)
    18                 line += lc[idx]
    19             fout.write("%s
    " % line)
    20             length = randint(100, 500)
    21             line = ""
    22             for i in xrange(length):
    23                 idx = randint(0, 25)
    24                 line += lc[idx]
    25             fout.write("%s
    " % line)
    26         fout.write("0
    ")
    27         
    28                 
    29 def MovDataIn():
    30     desFileName = "F:eclipse_prjworkspacehdojdata.in"
    31     shutil.copyfile("data.in", desFileName)
    32 
    33     
    34 if __name__ == "__main__":
    35     GenDataIn()
    36     MovDataIn()
  • 相关阅读:
    Linux命令之 文件归档管理
    C#总结项目《影院售票系统》编写总结完结篇
    C#总结项目《影院售票系统》编写总结三
    C#中MD5加密
    C#中的序列化与反序列化
    C#总结项目《影院售票系统》编写总结二
    C#总结项目《影院售票系统》编写总结一
    java多线程与线程并发四:线程范围内的共享数据
    java多线程与线程并发三:线程同步通信
    java多线程与线程并发二:线程互斥
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5179916.html
Copyright © 2020-2023  润新知