Advertisement
RaFiN_

aho corasick and dp

Mar 25th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. int l,r,k,n,m;int sz;int ending[1005];int to[1005][50],link[1005];string ss[1005],str;int dp[1005][1005],vis[1005][1005];
  2.  
  3. void Insert(string s,int indx){
  4.  
  5.     int curr = 0;
  6.     int len = s.length();
  7.     for(int i = 0;i<len;i++){
  8.  
  9.         int id = s[i] - 97;
  10.         if(!to[curr][id])to[curr][id] = ++sz;
  11.         curr = to[curr][id];
  12.  
  13.     }
  14.     ending[curr]++;
  15.     ///cout<<curr<<" lklklkl "<<endl;
  16. }
  17.  
  18.  
  19. void failure()
  20. {
  21.     int curr = 0;
  22.     link[curr] = -1;
  23.     queue<int>q;
  24.     q.push(curr);
  25.     while(!q.empty()){
  26.  
  27.         int x = q.front();
  28.         q.pop();
  29.         for(int i = 0;i<26;i++){
  30.  
  31.             if(!to[x][i])continue;
  32.             if(!x)link[to[x][i]] = 0;
  33.             else {
  34.                 int y = x;
  35.                 while(link[y]!=-1){
  36.  
  37.                     if(to[link[y]][i]){
  38.  
  39.                         link[to[x][i]] = to[link[y]][i];
  40.                         break;
  41.                     }
  42.                     y = link[y];
  43.                 }
  44.                 if(link[y]==-1)link[to[x][i]] = 0;
  45.             }
  46.             ending[to[x][i]]+=ending[link[to[x][i]]];
  47.             q.push(to[x][i]);
  48.  
  49.         }
  50.     }
  51. }
  52.  
  53. void CLEAR()
  54. {
  55.     for(int i = 0;i<1005;i++){
  56.  
  57.         for(int j = 0;j<1005;j++){
  58.  
  59.             dp[i][j] = -1;to[i][j] =  vis[i][j] = 0;
  60.         }
  61.         link[i] = ending[i] = 0;
  62.     }
  63.     sz = 0;
  64. }
  65.  
  66. void print(int pos,int id)
  67. {
  68.  
  69.     if(pos==n)return;
  70.     int &ret = vis[pos][id];
  71.     if(ret!=0)return ;
  72.     ret = 1;
  73.     int pk = str[pos] - 97;
  74.     if(str[pos]=='?'){
  75.         int mx = -1,ik,st;
  76.         for(int i = 0;i<26;i++){
  77.  
  78.             int state = id;
  79.             while(state!=-1&&to[state][i]==0)state = link[state];
  80.             if(state==-1)state = 0;
  81.             state = to[state][i];
  82.             int x = dp[pos+1][state]+ending[state];
  83.             if(x>mx){
  84.                 mx = x;
  85.                 ik = i;
  86.                 st = state;
  87.             }
  88.         }
  89.         cout<<(char)(ik+'a');
  90.         print(pos+1,st);
  91.     }
  92.     else {
  93.  
  94.         int state = id;
  95.         while(state!=-1&&to[state][pk]==0)state = link[state];
  96.         if(state==-1)state = 0;
  97.         state = to[state][pk];
  98.         cout<<str[pos];
  99.         print(pos+1,state);
  100.     }
  101.  
  102. }
  103.  
  104. int giveres(int pos,int id){
  105.     if(pos==n)return 0;
  106.     int &ret = dp[pos][id];
  107.     if(ret!=-1)return ret;
  108.     ret = 0;
  109.     int pk = str[pos] - 'a';
  110.     if(str[pos]=='?'){
  111.         for(int i = 0;i<26;i++){
  112.  
  113.             int state = id;
  114.             while(state!=-1&&to[state][i]==0)state = link[state];
  115.             if(state==-1)state = 0;
  116.             state = to[state][i];
  117.             ret = max(ret,giveres(pos+1,state)+ending[state]);
  118.         }
  119.     }
  120.     else {
  121.  
  122.         int state = id;
  123.         while(state!=-1&&to[state][pk]==0)state = link[state];
  124.         if(state==-1)state = 0;
  125.         state = to[state][pk];
  126.         ///cout<<ending[state].size()<<endl;
  127.         ret = max(ret,giveres(pos+1,state)+ending[state]);
  128.     }
  129.     return ret;
  130.  
  131. }
  132.  
  133.  
  134. int main()
  135. {
  136.     ///booster()
  137.     ///read("input.txt");
  138.  
  139.     int t;
  140.     cin>>t;
  141.     while(t--){
  142.  
  143.         CLEAR();
  144.         cin>>n>>m;
  145.         cin>>str;
  146.         for(int i = 0;i<m;i++){
  147.             cin>>ss[i];
  148.             Insert(ss[i],i);
  149.         }
  150.         failure();
  151.         cout<<giveres(0,0)<<endl;
  152.         for(int i = 0;i<1005;i++)for(int j = 0;j<1005;j++)if(dp[i][j]==-1)dp[i][j] = 0;
  153.         print(0,0);
  154.         cout<<endl;
  155.  
  156.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement