• ACM-ICPC 2018 南京赛区网络预赛 Skr 马拉车+字符串hash+hash表


    题目链接:Skr

    题意,求不同的回文串的和。

    题解:马拉车的时候当找到一个新的回文串时,判断这个回文串的hash值是否在hashmap中,没有就加入然后ans加上这段值,有就不管

    #include<bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int base=23;
    const int N=2e6+100;
    const int mod=1e9+7;
    struct hash
    {
        char s[N];
        ull h[N],qp[N];
        ll p[N],len,val[N];
        void init()
        {
            h[0]=val[0]=0;
            qp[0]=p[0]=1;
            len=strlen(s+1);
            for(int i=1;i<=len;i++)
            {
                p[i]=p[i-1]*10%mod;
                qp[i]=qp[i-1]*base;
                h[i]=h[i-1]*base+s[i];
                val[i]=(1LL*val[i-1]*10%mod+s[i]-'0')%mod;
            }
        }
        ull get_hash(int l,int r)
        {
            return h[r]-h[l-1]*qp[r-l+1];
        }
        int get_val(int l,int r)
        {
            return ((val[r]-val[l-1]*p[r-l+1]%mod)%mod+mod)%mod;
        }
    }ac;
    int mx,len[N],x;
    ll ans;
    const int HASH = 1000007;
    const int maxn=1e7+7;
    struct hashmap{
        ll a[maxn];
        int head[HASH],nxt[maxn],sz;
        void init(){
            memset(head,-1,sizeof(head));
            sz = 0;
        }
        bool find(ull val){
            int tmp = (val%HASH + HASH) % HASH;
            for(int i = head[tmp] ; ~i ; i = nxt[i]){
                if(val == a[i]) return true;
            }
            return false;
        }
        void add(ull val){
            int tmp = (val%HASH + HASH) % HASH;
            if(find(val)) return;
            a[sz] = val;
            nxt[sz] = head[tmp];
            head[tmp] = sz ++;
        }
    }ap;
    void ins(int l,int r)
    {
        ull h=ac.get_hash(l,r);
        if(!ap.find(h))
        {
            ap.add(h);
            ans+=ac.get_val(l,r);
            ans%=mod;
        }
    }
    int main(){
        scanf("%s",ac.s+1);
        ac.init();
        ap.init();
        //int mx=0,x=0;
        for(int i=1;i<=ac.len;i++)
        {
            ins(i,i);
            if(mx>i)len[i]=min(mx-i,len[2*x-i]);
            while(i+len[i]+1<=ac.len&&ac.s[i+len[i]+1]==ac.s[i-len[i]-1])
            {
                ins(i-len[i]-1,i+len[i]+1);
                len[i]++;
            }
            if(i+len[i]>mx)
            {
                mx=i+len[i];x=i;
            }
        }
        mx=x=0;
        memset(len,0,sizeof len);
        ap.init();
        for(int i=2;i<=ac.len;i++)
        {
            if(mx>i)len[i]=min(mx-i+1,len[2*x-i]);
            while(i+len[i]<=ac.len&&ac.s[i+len[i]]==ac.s[i-len[i]-1])
            {
               ins(i-len[i]-1,i+len[i]);
                len[i]++;
            }
            if(i+len[i]-1>mx)
            {
                mx=i+len[i]-1;x=i;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    2.4 学习总计 之 自己实现底部导航
    2.3 学习总结 之 分页查询
    2.2 学习总结 之 servlet 的两次抽取
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9743229.html
Copyright © 2020-2023  润新知