• CF 1200E HASH模板


    一道字符串题,从前往后压缩句子

    每次可以把已有的后缀与带添加的前缀相同的部分压缩掉,问最短压缩后的句子

    显然这道题就是要做一个字符串匹配的工作,所以Kmp肯定可以做,但是后来看了一下好像会被卡常数,还是要稍微优化一点的,

    这里因为在练hash,所以就用hash做了。

    这里我们要的是l,r的哈希值,而且要O(1)获得,不能每次重做,所以就用类似前缀和的思想,开两个数组差分一下就可以(大概是叫这个?)

    然后冲浪的时候发现一个很好的板子,正好用上测一下,还可以适用于多哈希。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=1000005;
     6 struct Hash{
     7     int base[4],mod[4];
     8     int tot,hash[4][maxn],pw[4][maxn]; //字符串长度,hash:记从1~i的hash值,pw:记录base^i
     9     Hash() {
    10         tot=0;
    11         for(int i=1;i<=3;i++) pw[i][0]=1;
    12         base[1]=233;base[2]=19260817;base[3]=20030714;
    13         mod[1]=1e9+7;mod[2]=1e9+9;mod[3]=998244353;
    14     }
    15 
    16     void init() {
    17         tot=0;
    18     }
    19     void insert(int c) {
    20         tot++;
    21         for(int i=1;i<=3;i++) hash[i][tot]=(1LL*hash[i][tot-1]*base[i]+c)%mod[i];
    22         for(int i=1;i<=3;i++) pw[i][tot]=(1LL*pw[i][tot-1]*base[i])%mod[i];
    23     }
    24     //字符串[l,r]hash值,type为第几个hash
    25     int query(int l,int r,int type) { 
    26         return (hash[type][r]-(1LL*hash[type][l-1]*pw[type][r-l+1]%mod[type])+mod[type])%mod[type];
    27     }
    28     //判断字符串u的[lu,ru]内的字符串和字符串v的[lv,rv]内的字符串是否相同
    29     friend bool same(Hash &u,int lu,int ru,Hash &v,int lv,int rv) { 
    30         if(ru-lu!=rv-lv) return false;
    31         for(int i=1;i<=3;i++) if(u.query(lu,ru,i)!=v.query(lv,rv,i)) return false;
    32         return true;
    33     }
    34 }h1,h2;
    35 int n;
    36 char s[1000005],res[1000005];
    37 int main(){
    38     h1.init();
    39     scanf("%d",&n);
    40     int len=0;
    41     for (int i=1; i<=n; i++){
    42         scanf("%s",s+1);
    43         int l=strlen(s+1);
    44         if (i==1){
    45             for (int j=1; j<=l; j++){
    46                 h1.insert(s[j]);
    47                 res[j]=s[j];
    48             }
    49             len=l;
    50         }
    51         else {
    52             int p=0;
    53             h2.init();
    54             for (int j=1; j<=l; j++){
    55                 h2.insert(s[j]);
    56                 if (same(h1,max(1,h1.tot-j+1),h1.tot,h2,1,h2.tot)) p=j;
    57             }
    58             for (int j=p+1; j<=l; j++){
    59                 h1.insert(s[j]);
    60                 res[++len]=s[j];
    61             }
    62         }
    63     }
    64     for (int i=1; i<=len; i++)
    65         printf("%c",res[i]);    
    66 }
    View Code
  • 相关阅读:
    Sublime Text 最佳插件列表(转)
    MyBatis入门(六)---mybatis与spring的整合
    MyBatis入门(五)---延时加载、缓存
    MyBatis入门(三)---多个参数
    MyBatis入门(二)---一对一,一对多
    AccessRandomFile多线程下载文件
    MyBatis入门(一)---基本使用
    JAVA基础学习day27--反射机制
    简明 Vim 练级攻略(转)
    JAVA基础学习day26--正则表达式
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/14036643.html
Copyright © 2020-2023  润新知