Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1) D. Frequency of String

 

https://codeforces.com/problemset/problem/963/Dnode

 

length distnctios

number <= sqrt(1e5)=316數組

全部串t出現次數<=1e5*315spa

 

對於某個串t出現的位置 遞增code

 

ac自動機一個點惟一指向另一個點blog

記錄須要合併的子孫下標,該節點已有的位置string

對於目標點,對數組進行合併。it

詳見代碼io

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream>
  8 using namespace std;
  9 #define ll long long
 10 #include <vector>
 11 
 12 const double eps=1e-8;
 13 const ll inf=1e9;
 14 const ll mod=1e9+7;
 15 const int maxn=1e5+10;
 16 const int maxm=sqrt(100)+10;
 17 
 18 /**
 19 all string are distinct
 20 **/
 21 
 22 struct node
 23 {
 24     int num,ind;
 25     node *nex[26],*pre,*fail;
 26 }*tr,*be,*pos,*p,*td,*q[maxn];
 27 
 28 char s[maxn],str[maxn];
 29 int least[maxn],re[maxn];
 30 int head1,tail1,d1,q1[maxn],cnt_least;
 31 
 32 vector<int> hap[maxn],son[maxn],temp,temp1;
 33 ///son:記錄有用的子孫節點的編號,只有處於目標點時才合併
 34 
 35 void arr_merge(int ind)
 36 {
 37     temp1.clear();
 38     vector<int>::iterator i=temp.begin(),j=hap[ind].begin(),i_end=temp.end(),j_end=hap[ind].end();
 39     while (i!=i_end && j!=j_end)
 40     {
 41         if (*i < *j)
 42             temp1.push_back(*i),i++;
 43         else
 44             temp1.push_back(*j),j++;
 45     }
 46     while (i!=i_end)
 47         temp1.push_back(*i),i++;
 48     while (j!=j_end)
 49         temp1.push_back(*j),j++;
 50     temp=temp1;
 51 }
 52 
 53 int main()
 54 {
 55     int n,N,len,i,d,head,tail,ind,num,ii,jj;
 56     vector<int>::iterator j;
 57     tr=new node();
 58     be=new node();
 59     tr->pre=be;
 60     tr->fail=be;
 61     be->fail=be;
 62     for (i=0;i<26;i++)
 63         be->nex[i]=tr;
 64 
 65     scanf("%s",s);
 66     scanf("%d",&n);
 67     for (N=1;N<=n;N++)
 68     {
 69         scanf("%d%s",&least[N],str);
 70         len=strlen(str);
 71         re[N]=strlen(str);
 72         pos=tr;
 73         for (i=0;i<len;i++)
 74         {
 75             d=str[i]-97;
 76             if (!pos->nex[d])
 77             {
 78                 p=new node();
 79                 pos->nex[d]=p;
 80                 p->pre=pos;
 81             }
 82             pos=pos->nex[d];
 83         }
 84         pos->num=N;
 85     }
 86 
 87     head=0,tail=1;
 88     q[1]=tr;
 89     while (head<tail)
 90     {
 91         head++;
 92         td=q[head];
 93         for (d=0;d<26;d++)
 94             if (td->nex[d])
 95             {
 96                 pos=td->fail;
 97                 while (!pos->nex[d])
 98                     pos=pos->fail;
 99                 td->nex[d]->fail=pos->nex[d];
100                 q[++tail]=td->nex[d];
101                 td->nex[d]->ind=tail;///
102             }
103     }
104 
105     len=strlen(s);
106     pos=tr;
107     for (i=0;i<len;i++)
108     {
109         d=s[i]-97;
110         while (!pos->nex[d])
111             pos=pos->fail;
112         pos=pos->nex[d];
113 
114         hap[pos->ind].push_back(i);
115     }
116 
117     for (i=tail;i>=1;i--)
118     {
119         pos=q[i];
120         ind=pos->ind;
121         num=pos->num;
122         if (num)
123         {
124             temp.clear();
125             head1=0,tail1=1;
126             q1[1]=ind;
127             while (head1<tail1)
128             {
129                 head1++;
130                 d1=q1[head1];
131                 if (!hap[d1].empty())
132                 {
133                     if (temp.empty())
134                         temp=hap[d1];
135                     else
136                         arr_merge(d1);
137                 }
138                 for (j=son[d1].begin();j!=son[d1].end();j++)
139                     q1[++tail1]=*j;
140             }
141             hap[ind]=temp;
142             son[ind].clear();
143 
144             cnt_least=inf;
145 //            printf("size =%d\n",hap[ind].size());
146             jj=hap[ind].size()-least[num];
147             for (ii=0;ii<=jj;ii++)
148                 cnt_least=min(cnt_least,hap[ind][ii+least[num]-1]-hap[ind][ii]);
149             if (cnt_least==inf)
150                 re[num]=-1;
151             else
152                 re[num]+=cnt_least;
153         }
154         if (!hap[ind].empty() || !son[ind].empty())
155             son[pos->fail->ind].push_back(ind);
156     }
157 
158     for (i=1;i<=n;i++)
159         printf("%d\n",re[i]);
160     return 0;
161 }

 

bitset方法ast

https://codeforces.com/contest/963/submission/37784765

代碼中

記錄文本串s某個字符的全部位置

在模式串中對於一個字符t[i],b[t[i]-'a']爲全部能夠對應的位置,左移i個單位;若是對於全部j,tmp某個位置都爲1,則tmp該個位置爲1,模式串t能夠與s+j匹配。

時間複雜度O(length(s)*sum(length(t))

相關文章
相關標籤/搜索