• *模板--字符串


    manacher

     1 //返回s的最长回文子串的长度
     2 int Manacher(char* s){
     3     int len=strlen(s);
     4     for(int i=len;i>=0;i--){
     5         s[2*i+2]=s[i];
     6         s[2*i+1]='#';
     7     }
     8     s[0]='*';
     9     int id=0,m=0;
    10     for(int i=2;i<len*2+1;i++){
    11         if(r[id]+id>i) r[i]=min(r[2*id-i],r[id]+id-i);
    12         else r[i]=1;
    13         while(s[i-r[i]]==s[i+r[i]]) r[i]++;
    14         if(id+r[id]<i+r[i]) id=i;
    15         if(m<r[i]) m=r[i];
    16     }
    17     return m-1;
    18 }
    View Code

    Tire树

     1 const int maxnode=50000*200+10;
     2 const int sigma=2;
     3 #define CLR(m,a) memset(m,a,sizeof(m))
     4 struct Trie{
     5     int ch[maxnode][sigma];
     6     int val[maxnode];  
     7     int sz;
     8     //添加需要的挂载信息
     9 
    10     void init(){
    11         CLR(ch[0],0);
    12         sz=1;
    13     }
    14     int idx(char c){return c-'0';}
    15     //插入字符串s,附加信息为v(v必须非零)
    16     void inser(char *s,int v){
    17         int u=0,n=strlen(s);
    18         for(int i=0;i<n;i++){
    19             int c=idx(s[i]);
    20             if(!ch[u][c]){
    21                 CLR(ch[sz],0);
    22                 ch[u][c]=sz++;
    23             }
    24             u=ch[u][c];
    25         }
    26         val[u]=v;
    27     }
    28     void find(char* s){
    29         int u=0,n=strlen(s);
    30         for(int i=0;i<n;i++){
    31             int c=idx(s[i]);
    32             if(!ch[u][c]) return -1;
    33             u=ch[u][c];
    34         }
    35         return val[u];
    36     }
    37 };
    View Code

     节点较多时用下面这个

     1 const int maxnode=2000010;
     2 const int sigma=26;
     3 //Trie树
     4 struct Trie{
     5     int head[maxnode],nex[maxnode];
     6     char ch[maxnode];
     7     int val[maxnode];
     8     int sz;
     9 
    10     void init(){
    11         head[0]=-1;
    12         sz=1;
    13     }
    14     //插入
    15     void insert_(char* s,int v){
    16         int u=0,v,n=strlen(s);
    17         for(int i=0;i<n;i++){
    18             int ok=0;
    19             for(v=head[u];~v;v=nex[v]) if(ch[v]==s[i]){
    20                 ok=1;
    21                 break;
    22             }
    23             if(!ok){
    24                 v=sz++;
    25                 ch[v]=s[i];
    26                 val[v]=0;
    27                 nex[v]=head[u];
    28                 head[u]=v;
    29                 head[v]=-1;
    30             }
    31             u=v;
    32         }
    33         val[u]=v;
    34     }
    35     //查询
    36     void query(char* s){
    37         int u=0,v,n=strlen(s);
    38         for(int i=0;i<n;i++){
    39             int ok=0;
    40             for(v=head[u];~v;v=nex[v]) if(ch[v]==s[i]){
    41                 ok=1;
    42                 u=v;
    43                 break;
    44             }
    45             if(!ok) return ;
    46         }
    47         return val[u];
    48     }
    49 };
    前向星

    01字典树

     1 const int maxnode = 100010 * 32;
     2 const int sigma = 2;
     3 struct Tre{
     4     int ch[maxnode][sigma];
     5     LL val[maxnode];
     6     int sz;
     7     void init(){
     8         sz = 1;
     9         val[0] = 0;
    10         memset(ch[0], 0, sizeof(ch[0]));
    11     }
    12     void add(LL x){
    13         int u = 0, n = 32;
    14         for(int i = n; i >= 0; i--){
    15             int c = (x >> i) & 1;
    16             if(!ch[u][c]){
    17                 memset(ch[sz], 0, sizeof(ch[sz]));
    18                 val[sz] = 0;
    19                 ch[u][c] = sz++;
    20             }
    21             u = ch[u][c];
    22         }
    23         val[u] = x;
    24     }
    25     //返回与x异或最大的值val[u];
    26     LL query(LL x){
    27         int u = 0, n = 32;
    28         for(int i = n; i >= 0; i--){
    29             int c = (x >> i) & 1;
    30             if(ch[u][c ^ 1]) u = ch[u][c ^ 1];
    31             else u = ch[u][c];
    32         }
    33         return val[u];
    34     }
    35 }tre;
    View Code

    KMP

     1 const int maxn=1000010;
     2 int pl,sl;   //要先计算长度!!!
     3 int nex[maxn];
     4 char s[maxn],p[maxn];
     5 int ans=0;//
     6 
     7 void getnex(char *p)
     8 {
     9     int j=0,k=-1;
    10     nex[0]=-1;
    11     while(j<pl){
    12         if(k==-1||p[j]==p[k]) nex[++j]=++k;
    13         else k=nex[k];
    14     }
    15 }
    16 //拿p去匹配s
    17 void KMP(char *s,char *p)
    18 {
    19     getnex(p);
    20     int i=0,j=0;
    21     while(i<sl){
    22         if(j==-1||s[i]==p[j]) {i++;j++;}
    23         else j=nex[j];
    24         if(j==pl) return i-pl+1;   //看问题需要!!!
    25     }
    26 }
    View Code
     1 //p是模板串
     2 const int maxn=1010;
     3 char s[maxn],p[maxn];
     4 int f[maxn];
     5 int lens,lenp;
     6 void getfail(char* p){
     7     f[0]=f[1]=0;
     8     for(int i=1;i<lenp;i++){
     9         int j=f[i];
    10         while(j&&p[j]!=p[i]) j=f[j];
    11         f[i+1]=p[i]==p[j]?j+1:0;
    12     }
    13     return ;
    14 }
    15 int KMP(char* s,char* p){
    16     lens=srelen(s);
    17     lenp=strlen(p);
    18     getfail(p);
    19     int j=0;
    20     for(int i=0;i<lens;i++){
    21         while(j&&s[i]!=p[j]) j=f[j];
    22         if(s[i]==p[j]) j++;
    23         if(j==lenp) return i-m+1;   //找到p
    24     } 
    25     return -1;  //没找到p
    26 }
    LRJ

    扩展KMP

     1 const int maxn = 100010;
     2 char s[maxn], t[maxn];
     3 int ex[maxn], nxt[maxn];
     4 int lens, lent;
     5 
     6 void getnxt(){
     7     nxt[0] = lent;
     8     int a = 0, p = 0;
     9     for(int i = 1; i < lent; i++){
    10         if(i >= p || i + nxt[i - a] >= p){
    11             if(i >= p) p = i;
    12             while(p < lent && t[p] == t[p - i]) p++;
    13             nxt[i] = p - i;
    14             a = i;
    15         }else nxt[i] = nxt[i - a];
    16     }
    17 }
    18 void exkmp(char *s, char *t, int *ex){
    19     getnxt(t);
    20     int a = 0, p = 0;
    21     for(int i = 0; i < lens; i++){
    22         if(i >= p || i + nxt[i - a] >= p){
    23             if(i >= p) p = i;
    24             while(p < lens && p - i < lent && s[p] == t[p - i]) p++;
    25             ex[i] = p - i;
    26             a = i;
    27         }else ex[i] = nxt[i - a];
    28     }
    29 }
    201803

    ac自动机

     1 const int maxnode=11000;
     2 const int sigma=26;
     3 const int maxn=160; //
     4 
     5 struct AC
     6 {
     7     int ch[maxnode][sigma];
     8     int f[maxnode],val[maxnode],last[maxnode];
     9     int sz;
    10     int cnt[maxn];  //
    11 
    12     void init()
    13     {
    14         CLR(ch[0],0);
    15         CLR(cnt,0);
    16         sz=1;
    17     }
    18     int idx(char c) {return c-'a';}
    19     
    20     void inser(char *s,int v)
    21     {
    22         int u=0,n=strlen(s);
    23         for(int i=0;i<n;i++){
    24             int c=idx(s[i]);
    25             if(!ch[u][c]){
    26                 CLR(ch[sz],0);
    27                 val[sz]=0;
    28                 ch[u][c]=sz++;
    29             }
    30             u=ch[u][c];
    31         }
    32         val[u]=v;
    33     }
    34     void print(int u)
    35     {
    36         if(u){
    37             cnt[val[u]]++;
    38             print(last[u]);
    39         }
    40     }
    41     void fin(char *s)
    42     {
    43         int n=strlen(s);
    44         int u=0;
    45         for(int i=0;i<n;i++){
    46             int c=idx(s[i]);
    47             while(u&&!ch[u][c]) u=f[u];
    48             u=ch[u][c];
    49             if(val[u]) print(u);
    50             else if(last[u]) print(last[u]);
    51         }
    52     }
    53     void getfail()
    54     {
    55         queue<int> q;
    56         f[0]=0;
    57         for(int c=0;c<sigma;c++){
    58             int u=ch[0][c];
    59             if(u){
    60                 f[u]=0;
    61                 q.push(u);
    62                 last[u]=0;
    63             }
    64         }
    65         while(!q.empty()){
    66             int r=q.front();
    67             q.pop();
    68             for(int c=0;c<sigma;c++){
    69                 int u=ch[r][c];
    70                 if(!u) continue;
    71                 q.push(u);
    72                 int v=f[r];
    73                 while(v&&!ch[v][c]) v=f[v];
    74                 f[u]=ch[v][c];
    75                 last[u]=val[f[u]]?f[u]:last[f[u]];
    76             }
    77         }
    78     }
    79 };
    非指针

    后缀数组

     1 int s[maxn];
     2 int sa[maxn], t1[maxn],t2[maxn],c[maxn];
     3 int h[maxn],rank[maxn];
     4 int n;
     5 void build_sa(int n, int m){
     6     int i, *x = t1, *y = t2;
     7     for(i = 0; i < m; i++) c[i] = 0;
     8     for(i = 0; i < n; i++) c[x[i] = s[i]]++;
     9     for(i = 1; i < m; i++) c[i] += c[i-1];
    10     for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
    11 
    12     for(int k = 1; k <= n; k <<= 1){
    13         int p = 0;
    14         for(i = n-k; i < n; i++) y[p++] = i;
    15         for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; 
    16         for(i = 0; i < m; i++) c[i] = 0;
    17         for(i = 0; i < n; i++) c[x[y[i]]]++;
    18         for(i = 1; i< m; i++) c[i] += c[i-1];
    19         for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
    20         swap(x,y);
    21         p = 1;
    22         x[sa[0]] = 0;
    23         for(i = 1; i < n; i++) 
    24           x[sa[i]] = y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]? p-1 : p++;
    25         if(p>=n) break;
    26         m=p;
    27     }
    28 }
    29 
    30 void geth(int n){
    31     int i, j, k=0;
    32     for(i = 0; i <= n; i++) rank[sa[i]]=i; 
    33     for(i = 0; i < n; i++) {
    34         if(k) k--;
    35         j = sa[rank[i]-1];
    36         while(s[i+k]==s[j+k]) k++;
    37         h[rank[i]] = k;
    38     }
    39 }
    View Code
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1001;
     4 
     5 //sa[i] :排名第 i 的后缀在哪(i 从 1 开始)
     6 //rk[i]:后缀 i 排第几 (i 从 0 开始)
     7 //h[i]:排名为 i 和 i-1 的两个后缀的最长公共前缀(LCP)长度 (i 从 2 开始)
     8 int s[maxn];
     9 int sa[maxn], t1[maxn],t2[maxn],c[maxn];
    10 int h[maxn],rk[maxn];
    11 void build_sa(int n, int m){
    12     int i, *x = t1, *y = t2;
    13     for(i = 0; i < m; i++) c[i] = 0;
    14     for(i = 0; i < n; i++) c[x[i] = s[i]]++;
    15     for(i = 1; i < m; i++) c[i] += c[i-1];
    16     for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
    17 
    18     for(int k = 1; k <= n; k <<= 1){
    19         int p = 0;
    20         for(i = n-k; i < n; i++) y[p++] = i;
    21         for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; 
    22         for(i = 0; i < m; i++) c[i] = 0;
    23         for(i = 0; i < n; i++) c[x[y[i]]]++;
    24         for(i = 1; i< m; i++) c[i] += c[i-1];
    25         for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
    26         swap(x,y);
    27         p = 1;
    28         x[sa[0]] = 0;
    29         for(i = 1; i < n; i++) 
    30           x[sa[i]] = y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]? p-1 : p++;
    31         if(p>=n) break;
    32         m=p;
    33     }
    34 }
    35 
    36 void geth(int n){
    37     int i, j, k=0;
    38     for(i = 1; i <= n; i++) rk[sa[i]]=i; 
    39     for(i = 0; i < n; i++) {
    40         if(k) k--;
    41         j = sa[rk[i]-1];
    42         while(s[i+k]==s[j+k]) k++;
    43         h[rk[i]] = k;
    44     }
    45 }
    46 
    47 int dp[maxn][20];
    48 void rmq_init(int n){
    49     int k = 0;
    50     while(1<<(k+1) <= n) k++; 
    51     for(int i = 1; i <= n; i++) dp[i][0] = h[i];
    52     for(int i = 1; i <= k; i++){
    53         for(int j = 1; j + (1<<i) - 1 <= n; j++){
    54             dp[i][j] = min(dp[i][j-1], dp[i+(1<<j-1)][j-1]);
    55         }
    56     }
    57 }
    58 int rmq(int a, int b){
    59     if(a > b) swap(a, b);  //    
    60     a++;
    61     int k = 0;
    62     while(1<<(k+1) <= b-a+1) k++;
    63     return min(dp[a][k], dp[b - (1<<k) + 1][k]);
    64 }
    65 char str[maxn];
    66 int main(){
    67     scanf("%s", str);
    68     int n = strlen(str);
    69     for(int i = 0; i <  n; i++) s[i] = str[i] - 'a' + 1;
    70     build_sa(n+1, 300);
    71     geth(n);
    72 //    for(int i = 1; i <= n; i++)  cout<<sa[i]<<" ";
    73 //    cout<<endl;
    74 //    for(int i = 0; i < n; i++) cout<<rk[i]<<" ";
    75 //    cout<<endl;
    76 //    for(int i = 2; i <= n; i++)  cout<<h[i]<<" ";
    77 //    cout<<endl;
    78 //    int a, b;
    79     rmq_init(n);
    80     while(scanf("%d %d", &a, &b))
    81         cout<<rmq(rk[a], rk[b])<<endl;
    82 }
    后缀树组+
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 1001;
      4 /*
      5  * 后缀数组
      6  * DC3算法,复杂度O(n)
      7  * 所有的相关数组都要开三倍 
      8  */
      9 const int MAXN = 2010;
     10 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb))
     11 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x)-tb) * 3 + 2)
     12 
     13 int wa[MAXN * 3], wb[MAXN * 3], wv[MAXN * 3], wss[MAXN * 3];
     14 
     15 int c0(int *r, int a, int b)
     16 {
     17     return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];
     18 }
     19 
     20 int c12(int k, int *r, int a, int b)
     21 {
     22     if(k == 2)
     23     {
     24         return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1));
     25     }
     26     else
     27     {
     28         return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]);
     29     }
     30 }
     31 
     32 void sort(int *r, int *a, int *b, int n, int m)
     33 {
     34     int i;
     35     for (i = 0; i < n; i++)
     36     {
     37         wv[i] = r[a[i]];
     38     }
     39     for (i = 0; i < m; i++)
     40     {
     41         wss[i] = 0;
     42     }
     43     for (i = 0; i < n; i++)
     44     {
     45         wss[wv[i]]++;
     46     }
     47     for (i = 1; i < m; i++)
     48     {
     49         wss[i] += wss[i - 1];
     50     }
     51     for (i = n - 1; i >= 0; i--)
     52     {
     53         b[--wss[wv[i]]] = a[i];
     54     }
     55 }
     56 
     57 void dc3(int *r, int *sa, int n, int m)
     58 {
     59     int i, j, *rn = r + n;
     60     int *san = sa + n, ta = 0, tb = (n+1)/3, tbc = 0, p;
     61     r[n] = r[n+1] = 0;
     62     for (i = 0; i < n; i++)
     63     {
     64         if (i % 3 != 0)
     65         {
     66             wa[tbc++] = i;
     67         }
     68     }
     69     sort(r + 2, wa, wb, tbc, m);
     70     sort(r + 1, wb, wa, tbc, m);
     71     sort(r, wa, wb, tbc, m);
     72     for (p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++)
     73     {
     74         rn[F(wb[i])] = c0(r, wb[i - 1], wb[i]) ? p - 1 : p++;
     75     }
     76     if (p < tbc)
     77     {
     78         dc3(rn, san, tbc, p);
     79     }
     80     else
     81     {
     82         for (i = 0; i < tbc; i++)
     83         {
     84             san[rn[i]] = i;
     85         }
     86     }
     87     for (i = 0; i < tbc; i++)
     88     {
     89         if (san[i] < tb)
     90         {
     91             wb[ta++] = san[i] * 3;
     92         }
     93     }
     94     if (n % 3 == 1)
     95     {
     96         wb[ta++] = n - 1;
     97     }
     98     sort(r, wb, wa, ta, m);
     99     for (i = 0; i < tbc; i++)
    100     {
    101         wv[wb[i] = G(san[i])] = i;
    102     }
    103     for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++)
    104     {
    105         sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
    106     }
    107     for (; i < ta; p++)
    108     {
    109         sa[p] = wa[i++];
    110     }
    111     for (; j < tbc; p++)
    112     {
    113         sa[p] = wb[j++];
    114     }
    115 }
    116 
    117 //  str和sa也要三倍
    118 void da(int str[], int sa[], int rank[], int height[], int n,int m)
    119 {
    120     for (int i = n; i < n * 3; i++)
    121     {
    122         str[i] = 0;
    123     }
    124     dc3(str, sa, n+1, m);
    125     int i, j, k = 0;
    126     for (i = 0; i <= n; i++)
    127     {
    128         rank[sa[i]] = i;
    129     }
    130     for (i = 0; i < n; i++)
    131     {
    132         if(k)
    133         {
    134             k--;
    135         }
    136         j = sa[rank[i] - 1];
    137         while (str[i + k] == str[j + k])
    138         {
    139             k++;
    140         }
    141         height[rank[i]] = k;
    142     }
    143 }
    144 //sa[i] :排名第 i 的后缀在哪(i 从 1 开始)
    145 //rk[i]:后缀 i 排第几 (i 从 0 开始)
    146 //h[i]:排名为 i 和 i-1 的两个后缀的最长公共前缀(LCP)长度 (i 从 2 开始)
    147 int s[maxn];
    148 int sa[maxn], t1[maxn],t2[maxn],c[maxn];
    149 int h[maxn],rk[maxn];
    150 int dp[maxn][20];
    151 void rmq_init(int n){
    152     int k = 0;
    153     while(1<<(k+1) <= n) k++; 
    154     for(int i = 1; i <= n; i++) dp[i][0] = h[i];
    155     for(int i = 1; i <= k; i++){
    156         for(int j = 1; j + (1<<i) - 1 <= n; j++){
    157             dp[i][j] = min(dp[i][j-1], dp[i+(1<<j-1)][j-1]);
    158         }
    159     }
    160 }
    161 int rmq(int a, int b){
    162     if(a > b) swap(a, b);  //    
    163     a++;
    164     int k = 0;
    165     while(1<<(k+1) <= b-a+1) k++;
    166     return min(dp[a][k], dp[b - (1<<k) + 1][k]);
    167 }
    168 char str[maxn];
    169 int main(){
    170     scanf("%s", str);
    171     int n = strlen(str);
    172     for(int i = 0; i <  n; i++) s[i] = str[i] - 'a' + 1;
    173     da(s, sa, rk, h, n, 300);
    174 //    for(int i = 3; i <= n; i++)  cout<<sa[i]<<" ";
    175 //    cout<<endl;
    176 //    for(int i = 0; i < n; i++) cout<<rk[i]<<" ";
    177 //    cout<<endl;
    178 //    for(int i = 2; i <= n; i++)  cout<<h[i]<<" ";
    179 //    cout<<endl;
    180     int a, b;
    181     rmq_init(n);
    182     while(scanf("%d %d", &a, &b))
    183         cout<<rmq(rk[a], rk[b])<<endl;
    184 }
    DC3
  • 相关阅读:
    风雨20年:我所积累的20条编程经验 (转)
    WPF中的Style(风格,样式)(转)
    WPF入门学习(转)
    关于Viual Studio 改变编辑器背景背景及背景图片(转)
    SSIS 控制流和数据流(转)
    修复 Firefox 下本地使用 Bootstrap 3 时 glyphicon 不显示问题
    .net字符串Gzip压缩和base64string转换:
    .net WebClient发送请求实例:
    XmlDocument解析Soap格式文件案例:
    Xml文件操作的其中一个使用方法:
  • 原文地址:https://www.cnblogs.com/yijiull/p/7247480.html
Copyright © 2020-2023  润新知