zoukankan      html  css  js  c++  java
  • LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)【Hash做法】By cellur925

    题目传送门

    其实这题正解是AC自动机的,字符串哈希吸氧才能过的,但是我太菜了不会...只能先用哈希苟了。


    在扫描单词的时候首先把各个单词的哈希值和长度存起来。然后按照长度从小到大将各单词排序。而那个长长的字符串呢,我们就把它一点一点往栈里塞,够最小长度单词的长度时,我们就比较下,这样反复下去。如果遇到相同的字符串,就把他们弹出。

    这个思路最巧妙的一点感觉就是用栈了。我自己写哈希的时候遇到删除的情况就布吉岛怎么搞了qwq。

    这里的哈希值不能预处理出来的,而是动态维护的。因为有可能会删掉子串。所以只需要预处理出p数组(131的乘方),然后动态求哈希值。

    Code

     1 // luogu-judger-enable-o2
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<iostream>
     6 
     7 using namespace std;
     8 typedef unsigned long long ull;
     9 
    10 int lenall,top,n;
    11 char sta[100090],tmp[100090],s[100090];
    12 ull b=131,f[100090],p[100090];
    13 struct dictionary{
    14     int len;
    15     ull has;
    16 }t[2000];
    17 
    18 bool cmp(dictionary a,dictionary b)
    19 {
    20     return a.len<b.len;
    21 }
    22 
    23 ull gethash(int l,int r)
    24 {
    25     return f[r]-f[l-1]*p[r-l+1];
    26 }
    27 
    28 int main()
    29 {
    30     scanf("%s",sta+1);
    31     p[0]=1;
    32     lenall=strlen(sta+1);
    33 /*    for(int i=1;i<=lenall;i++)
    34     {
    35         f[i]=f[i-1]*131+(sta[i]-'a'+1);
    36         p[i]=p[i-1]*131;
    37     }*/
    38     scanf("%d",&n);
    39     for(int i=1;i<=n;i++)
    40     {
    41         scanf("%s",tmp+1);
    42         t[i].len=strlen(tmp+1);
    43         for(int j=1;j<=t[i].len;j++)
    44             t[i].has=t[i].has*b+tmp[j];
    45     }
    46     sort(t+1,t+1+n,cmp);
    47     for(int i=1;i<=lenall;i++)
    48         p[i]=p[i-1]*b;
    49     for(int i=1;i<=lenall;i++)
    50     {
    51         s[++top]=sta[i];
    52         f[top]=f[top-1]*b+s[top];
    53         while(top<t[1].len&&i<lenall)
    54             s[++top]=sta[++i],f[top]=f[top-1]*b+s[top];
    55         for(int j=1;j<=n&&top;j++)
    56             if(top-t[j].len+1>=1&&t[j].has==gethash(top-t[j].len+1,top))
    57                 top-=t[j].len;
    58     }
    59     for(int i=1;i<=top;i++)
    60         cout<<s[i]; 
    61     cout<<endl;
    62     return 0;
    63 }
    View Code

     

  • 相关阅读:
    易用网页下载器V0.1
    重复造轮之权限管理系统
    网页格式化排版代码,专用信息采集后的内容整理
    随机点名软件
    PHP导入Excel表格,读取Excel的内容到数组。
    汉字的书写效果的实现
    php的一个断点续传下载实现
    sentry的安装和使用以及各种问题处理
    CentOS下安装Redis及Redis的PHP扩展
    用ASP.NET_Regsql.exe创建Session数据库
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9768507.html
Copyright © 2011-2022 走看看