欢迎来到SFWR的博客

[CF#578]E. Compress Words

将n个字符串缩为一个字符串

————————————————————————————

借这个题学习一下double hash

还是需要好好练习的

KMP还是算了,没在计划中

————————————————————————————

#include<bits/stdc++.h>
using namespace std;
const int p1=1331,p2=13331,mod=1003020617;
int pow1[1000100],pow2[1000100],la1[1000100],la2[1000100],nxt1[1000100],nxt2[1000100];
char ch[1000100],now[1000100];
int t,l=0;
int check1(int cur)
{
    int x1=nxt1[cur];
    int x2=((la1[l]-1ll*la1[l-cur]*pow1[cur])%mod+mod)%mod;
    return x1==x2;
}
int check2(int cur)
{
    int x1=nxt2[cur];
    int x2=((la2[l]-1ll*la2[l-cur]*pow2[cur])%mod+mod)%mod;
    return x1==x2;
}
int main()
{   
    pow1[0]=pow2[0]=1;
    for(int i=1;i<=1000100;i++){pow1[i]=1ll*pow1[i-1]*p1%mod;pow2[i]=1ll*pow2[i-1]*p2%mod;}
    cin>>t;
    while(t--)
    {
    cin>>(now+1);
    int len=strlen(now+1),cur;
    for(int j=1;j<=len;j++)
    {
        nxt1[j]=(1ll*nxt1[j-1]*p1+now[j]-'0'+1)%mod;
        nxt2[j]=(1ll*nxt2[j-1]*p2+now[j]-'0'+1)%mod;
    }
    for(cur=len;cur;cur--)
    if(l>=cur&&check1(cur)&&check2(cur))break;    
    for(int j=cur+1;j<=len;j++)
    {
        ch[++l]=now[j];
        la1[l]=(1ll*la1[l-1]*p1+now[j]-'0'+1)%mod;
        la2[l]=(1ll*la2[l-1]*p2+now[j]-'0'+1)%mod;
    }
    }
    cout<<(ch+1);
}

 

posted @ 2019-08-15 20:26  SFWR  Views(174)  Comments(0Edit  收藏  举报