• POJ3974 字符串哈希+二分


    题目:http://poj.org/problem?id=3974

    本来是想练习一下字符串哈希算法的,没想到改了好久的二分,23333。

    求字符串中的最长回文字串以前我一直用的dp,当然这道题用dp会T。用哈希+二分可以达到O(NlogN)的时间复杂度。

    首先进行正反两次字符串哈希。哈希方法

    然后分长度为奇数或偶数两种情况,对于每一个位置i,二分它向一个方向可以延伸的长度,判断使用之前预处理的字符串哈希。

    当然二分要注意方法,不然可能会wa掉。

    这道题要求取满足条件的最大值,应该这样二分:

    int Division()
    {
        int l=ledge,r=redge;
        while(l<r)
        {
            int mid=(l+r+1)>>1;
            if(judge(mid)) l=mid;
            else r=mid-1;
        }
        return l;
    }

    而很多题可能求满足条件的最小值,这样二分:

    int Division()
    {
        int l=ledge,r=redge;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(judge(mid)) l=mid+1;
            else r=mid;
        }
        return l;
    }
    View Code

    附上ac代码:

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    typedef unsigned long long ULL;
    char s1[1000010],s2[1000010];
    ULL f1[1000010],f2[1000010],p[1000010];
    int len=0;
    
    int OddDivision(int i)
    {
        int l=0,r=min(i-1,len-i);
        while(l<r)
        {
            int mid=(l+r+1)>>1;
            if(f1[i-1]-f1[i-mid-1]*p[mid]==f2[len-i]-f2[len-i-mid]*p[mid])
                l=mid;
            else r=mid-1;
        }
        return l;
    }
    
    int EveDivision(int i)
    {
        int l=0,r=min(i-1,len-i+1);
        while(l<r)
        {
            int mid=(l+r+1)>>1;
            if(f1[i-1]-f1[i-mid-1]*p[mid]==f2[len-i+1]-f2[len-i+1-mid]*p[mid])
                l=mid;
            else r=mid-1;
        }
        return l;
    }
    
    int main()
    {
        int Case=0;
        while(~scanf("%s",s1+1))
        {
            Case++;
            if(!strcmp(s1+1,"END")) break;
            len=strlen(s1+1);
            for(int i=len;i>=1;i--) s2[len-i+1]=s1[i];s2[len+1]='';
            p[0]=1;
            for(int i=1;i<=len;i++)
            {
                f1[i]=f1[i-1]*131+s1[i]-'a'+1;
                f2[i]=f2[i-1]*131+s2[i]-'a'+1;
                p[i]=p[i-1]*131;
            }
            int ans=0;
            for(int i=1;i<=len;i++)
            {
                int odd=OddDivision(i);
                ans=max(ans,odd*2+1);
                int eve=EveDivision(i);
                ans=max(ans,eve*2);
            }
            printf("Case %d: %d
    ",Case,ans);
        }
        return 0;
    }
  • 相关阅读:
    Python3 input() 函数
    Python3 enumerate() 函数
    Python3 ascii() 函数
    Python3 sorted() 函数
    css sprite
    Java 理论与实践: 并发集合类
    关于 Java Collections API 您不知道的 5 件事,第 1 部分
    Treasure! Free Mobile Design Resources
    Indigo Studio
    ionic:Build mobile apps faster with the web technologies you know and love
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11307794.html
Copyright © 2020-2023  润新知