zoukankan      html  css  js  c++  java
  • 补题:Div2 #578 E. Compress Words

    补题:Div2 #578 E. Compress Words

    从第一个单词开始,如果前一个单词的后缀和后一个单词的前缀相同,那么把他们合并,求最后合并后的串

    每新读入一个新字符串就将其和已有的字符串合并,不是合并i和i-1

    想法就是对想合并的两个串求哈希值,然后枚举能合并的前缀后缀的长度

    单模数hash在codeforces上很容易被hack的,建议双模数hash

    如果时间超限的话,可以考虑预处理快速幂,能少个log

    (hash查询是O(1)的,所以在某些情况下可以往稍稍暴力的方面想)

    (太久没写被卡细节=_=)

    #include<bits/stdc++.h>
    using namespace std;
    #define PI acos(-1)
    #define ll long long
    #define clean(a,b) memset(a,b,sizeof(a))
    const int inf=0x3f3f3f3f;
    const int maxn=1e6+9;
    const int mod=1e9+7;
    const int mod_=1e9+9;
    inline ll read()
    {
        register ll x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
        return x*f;
    }
    string s[maxn];
    int base=131;
    ll _hash[1000009][6];
    int fpo[maxn][3];
    ll fpow(ll a,ll b,ll c)
    {
        a%=c;
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%c;
            a=a*a%c;
            b>>=1;
        }
        return ans%c;
    }
    
    int get_hash(int l,int r,int x)
    {
        return (_hash[r+1][x]-_hash[l][x]*fpo[r-l+1][1]%mod+mod)%mod;
    }
    int get_hash_(int l,int r,int x)
    {
        return (_hash[r+1][x]-_hash[l][x]*fpo[r-l+1][2]%mod_+mod_)%mod_;
    }
    
    int main()
    {
    #ifdef LOCAL
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        for(int i=1;i<=1e6;i++) fpo[i][1]=fpow(base,i,mod)%mod,fpo[i][2]=fpow(base,i,mod_)%mod_;
        int n=read();
        cin>>s[1];
        int len=s[1].size();
        // int now=2;//now 
        for(int i=0;i<len;i++)
        {
            _hash[i+1][1]=((_hash[i][1]*base)+s[1][i])%mod;
            _hash[i+1][3]=((_hash[i][3]*base)+s[1][i])%mod_;
        }
        string ans=s[1];
        for(int i=2;i<=n;i++)
        {
            cin>>s[i];
            int len=s[i].size();
            int anslen=ans.size();
            int nowlen=min(len,anslen);
            for(int j=0;j<len;j++)
            {
                _hash[j+1][2]=((_hash[j][2]*base)+s[i][j])%mod;
                _hash[j+1][4]=((_hash[j][4]*base)+s[i][j])%mod_;
            }
            int anss=0;
            for(int j=1;j<=nowlen;j++)
            {
                ll hash_1=get_hash(anslen-j,anslen-1,1);
                ll hash_2=get_hash(0,j-1,2);
                ll hash_3=get_hash_(anslen-j,anslen-1,3);
                ll hash_4=get_hash_(0,j-1,4);
                if(hash_1==hash_2) anss=j;
            }
            for(int j=anss;j<len;j++)
            {
                int k=j-anss+anslen;
                _hash[k+1][1]=((_hash[k][1]*base)+s[i][j])%mod;
                _hash[k+1][3]=((_hash[k][3]*base)+s[i][j])%mod_;
                ans+=s[i][j];
            }
        }
        cout<<ans;
        return 0;
    }
    /*
    12345678
    678945646
    
    */
    
    
  • 相关阅读:
    前端安全
    关于HTTPS的概念性了解
    数组去重
    防抖与节流
    对meta标签的再次认识
    关于路由, 我好奇的那些点
    关于构造函数,实例,原型对象一纯手工的理解
    数据库查找操作-java
    python之图像加载和简单处理
    python之excel表格操作
  • 原文地址:https://www.cnblogs.com/YangKun-/p/15016569.html
Copyright © 2011-2022 走看看