zoukankan      html  css  js  c++  java
  • zoj 3228 Searching the String

    题意:

      给一个1e5长只有小写字母的串,1e5个询问,问某个串在可以重叠或者不可以重叠的条件下最大匹配数。

    解法:

      最开始的时候在Trie的每个节点把所有出现的单词编号全塞到vector里,结果TLE到死。其实如果在插入的时候,以同一个节点作为终止节点的只有那一个。。所以对一个串只插入一次就行,然后自动机匹配的时候分别统计可以重叠和不可以重叠的匹配数。

      可以重叠的匹配只要在自动机上跑就行,对于不可以重叠的,记录一下上次匹配的位置,然后判断一下是否满足条件就行。。

      字符串判重的时候我写了个双重hash。。。

      1 #include<cstdio>
      2 #include<map>
      3 #include<cstring>
      4 #include<queue>
      5 #include<algorithm>
      6 using namespace std;
      7 const int N = (int)1e6+10;
      8 const int M = (int)1e5+5;
      9 struct node{
     10     node *ch[26],*fail;
     11     int index,deep;
     12     void clear(){
     13         for(int i = 0;i < 26;i++)ch[i] = NULL;
     14         fail = NULL;
     15         index = 0;
     16         deep = 0;
     17     }
     18 };
     19 node stk[N];
     20 bool type[M];
     21 int last[M],vis[M][2];
     22 struct Trie{
     23     node *root;
     24     int top;
     25     node* new_node(){
     26         node *p = &stk[top++];
     27         p -> clear();
     28         return p;
     29     }
     30     void init(){
     31         top = 0;
     32         root = new_node();
     33     }
     34     void insert(char *s,int index){
     35         node *p = root;
     36         for(int i = 0;s[i];i++){
     37             int id = s[i] - 'a';
     38             if(p -> ch[id] == NULL)
     39                 p -> ch[id] = new_node();
     40             p = p -> ch[id];
     41             p -> deep = i + 1;
     42         }
     43         p -> index = index;
     44     }
     45     void build(){ 
     46         queue<node*> Q;
     47         root -> fail = NULL;
     48         for(int i = 0;i < 26;i++)
     49             if(root -> ch[i] == NULL)
     50                 root -> ch[i] = root;
     51             else{
     52                 Q.push(root -> ch[i]);
     53                 root -> ch[i] -> fail = root;
     54             }
     55         while(!Q.empty()){
     56             node  *p = Q.front();Q.pop();
     57             for(int i = 0;i < 26;i++)
     58                 if(p -> ch[i] == NULL)
     59                     p -> ch[i] = p -> fail -> ch[i];
     60                 else{
     61                     Q.push(p -> ch[i]);
     62                     p -> ch[i] -> fail = p -> fail -> ch[i];
     63                 }
     64         }
     65     }
     66     void solve(char *s){
     67         node *p = root;
     68         for(int i = 0;s[i];i++){
     69             int id = s[i] - 'a';
     70             p = p -> ch[id];
     71             node *u = p;
     72             while(u != root){
     73                 int cur = u -> index;
     74                 if(cur){
     75                     vis[cur][0]++;
     76                     if(last[cur] == -1){
     77                         vis[cur][1]++;
     78                         last[cur] = i;
     79                     }else if(i - last[cur] >= u->deep){
     80                         vis[cur][1]++;
     81                         last[cur] = i;
     82                     }
     83                 }
     84                 u = u -> fail;
     85             }
     86         }
     87     }
     88 };
     89 Trie AC;
     90 char s[M];
     91 typedef unsigned long long ull;
     92 map<pair<ull,ull>,int>Map;
     93 int number[M];
     94 inline pair<ull,ull> geths(char *s){
     95     pair<ull,ull> ans(0,0);
     96     int len = strlen(s);
     97     for(int i = 0;i < len;i++){
     98         ans.first = ans.first * 31 + s[i];
     99         ans.second = ans.second * 131 + s[i];
    100     }
    101     return ans;
    102 }
    103 int main(){
    104     int cas = 1,n;
    105     while(~scanf("%s",s)){
    106         scanf("%d",&n);
    107         AC.init();
    108         int cnt = 0;
    109         Map.clear();
    110         for(int i = 1;i <= n;i++){
    111             char x[10];int flag;
    112             scanf("%d%s",&flag,x);
    113             type[i] = flag;
    114             vis[i][0] = vis[i][1] = 0;
    115             last[i] = -1;
    116             pair<ull,ull> hs = geths(x);
    117             if(!Map.count(hs)){
    118                 Map[hs] = ++cnt;
    119                 AC.insert(x,Map[hs]);
    120             }
    121             number[i] = Map[hs];
    122         }
    123         AC.build();
    124         AC.solve(s);
    125         printf("Case %d
    ",cas++);
    126         for(int i = 1;i <= n;i++)
    127             printf("%d
    ",vis[number[i]][type[i]]);
    128         puts(""); 
    129     }
    130     return 0;
    131 }
  • 相关阅读:
    ll command not found 当ll无法识别的解决办法
    idea控制台全屏
    查看centos版本号
    java Error: 无法访问org.apache.http.annotation.ThreadSafe 找不到org.apache.http.annotation.ThreadSafe的类文件
    DigestUtils.md5Hex()加密
    JAVA 8 '::' 关键字
    CVE-2020-1472 NetLogon特权提升漏洞
    OpenSSH的scp命令注入漏洞(CVE-2020-15778)
    redis未授权访问漏洞&简单利用&总结
    常见web信息泄露
  • 原文地址:https://www.cnblogs.com/silver-bullet/p/3244858.html
Copyright © 2011-2022 走看看