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

     

  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9768507.html
Copyright © 2011-2022 走看看