zoukankan      html  css  js  c++  java
  • POJ 3974 Palindrome (算竞进阶习题)

    hash + 二分答案

    数据范围肯定不能暴力,所以考虑哈希。
    把前缀和后缀都哈希过之后,扫描一边字符串,对每个字符串二分枚举回文串长度,注意要分奇数和偶数

    #include <iostream>
    #include <cstdio>
    #define INF 0x3f3f3f3f
    #define full(a, b) memset(a, b, sizeof a)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int X = 0, w = 0; char ch = 0;
        while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
        while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
        return w ? -X : X;
    }
    inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
    inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
    template<typename T>
    inline T max(T x, T y, T z){ return max(max(x, y), z); }
    template<typename T>
    inline T min(T x, T y, T z){ return min(min(x, y), z); }
    template<typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    
    const int N = 1000005;
    const int P = 131;
    ull f[N], p[N], rf[N];
    char s[N];
    int ans, n, cnt;
    
    int solve1(int i){
        int l = 0, r = min(i - 1, n - i);
        while(l < r){
            int mid = (l + r + 1) >> 1;
            if(f[i] - f[i - mid - 1] * p[mid + 1] == rf[i] - rf[i + mid + 1] * p[mid + 1])
                l = mid;
            else r = mid - 1;
        }
        return l;
    }
    
    int solve2(int i){
        int l = 0, r = min(i - 1, n - i + 1);
        while(l < r){
            int mid = (l + r + 1) >> 1;
            if(f[i - 1] - f[i - mid - 1] * p[mid] == rf[i] - rf[i + mid] * p[mid])
                l = mid;
            else r = mid - 1;
        }
        return l;
    }
    
    int main(){
    
        while(1){
            scanf("%s", s + 1);
            n = strlen(s + 1);
            if(n == 3 && s[1] == 'E' && s[2] == 'N' && s[3] == 'D') break;
            full(p, 0), full(f, 0), full(rf, 0);
            ans = 0;
            p[0] = 1;
            for(int i = 1; i <= n; i ++){
                f[i] = f[i - 1] * P + (s[i] - 'a' + 1);
                p[i] = p[i - 1] * P;
            }
            for(int i = n; i >= 1; i --){
                rf[i] = rf[i + 1] * P + (s[i] - 'a' + 1);
            }
            for(int i = 1; i <= n; i ++){
                ans = max(ans, 2 * solve1(i) + 1);
                ans = max(ans, 2 * solve2(i));
            }
            printf("Case %d: %d
    ", ++cnt, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Elasticsearch集群+kibana
    kafka集群搭建
    Zookeeper集群搭建
    Hadoop+Hbase+Zookeeper分布式存储构建
    正则文本处理
    Haproxy+keepalived高可用集群实战
    httpsqs消息队安装
    LVS-TUN模式
    一.4.序列化使用之机柜资源及序列化高级用法
    一.3.序列化使用之idc资源与api文档
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10732307.html
Copyright © 2011-2022 走看看