zoukankan      html  css  js  c++  java
  • [BZOJ3790]神奇项链

    [BZOJ3790]神奇项链

    试题描述

    母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
    母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。 

    输入

    输入数据有多行,每行一个字符串,表示目标项链的样式。

    输出

    多行,每行一个答案表示最少需要使用第二个机器的次数。

    输入示例

    abcdcba
    abacada
    abcdef

    输出示例

    0
    2
    5

    数据规模及约定

    每个测试数据,输入不超过 5行 

    每行的字符串长度小于等于 50000 

    题解

    可以 dp 一下,设 f[i] 表示前 i 个字符中,最少由几个回文串可重叠地拼接而成,那么每次转移我们可以找到位置 i 的 P[i],查询 [i - P[i] + 1, n] 这个区间中的最小值 minv,然后用 minv + 1 更新 f[i+P[i]-1]。用线段树可以很容易地优化。

    当然求出 P[i] 数组后,每个位置 i 可以转化成 [i - P[i] + 1, i + P[i] - 1] 这样的区间,然后贪心就好了。

    这里只放线段树 + dp 的版本。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
     
    #define maxn 100010
    #define oo 2147483647
     
    int f[maxn], mnv[maxn<<2];
    void build(int L, int R, int o) {
        if(L == R) mnv[o] = f[L] = oo;
        else {
            int M = L + R >> 1, lc = o << 1, rc = lc | 1;
            build(L, M, lc); build(M+1, R, rc);
            mnv[o] = min(mnv[lc], mnv[rc]);
        }
        return ;
    }
    void update(int L, int R, int o, int p, int v) {
        if(L == R) mnv[o] = f[L] = v;
        else {
            int M = L + R >> 1, lc = o << 1, rc = lc | 1;
            if(p <= M) update(L, M, lc, p, v);
            else update(M+1, R, rc, p, v);
            mnv[o] = min(mnv[lc], mnv[rc]);
        }
        return ;
    }
    int query(int L, int R, int o, int ql, int qr) {
        if(ql <= L && R <= qr) return mnv[o];
        int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = oo;
        if(ql <= M) ans = min(ans, query(L, M, lc, ql, qr));
        if(qr > M) ans = min(ans, query(M+1, R, rc, ql, qr));
        return ans;
    }
     
    int Len[maxn];
    char Str[maxn], S[maxn];
     
    int main() {
        while(scanf("%s", Str + 1) == 1) {
            int n = strlen(Str + 1);
            for(int i = 1; i <= n; i++) S[i<<1] = Str[i], S[(i<<1)-1] = '#';
            n = n << 1 | 1; S[n] = '#';
    //      S[n+1] = ''; printf("%s
    ", S + 1);
            int mxi = 0;
            for(int i = 1; i <= n; i++) {
                int mxp = mxi + Len[mxi] - 1;
                if(mxp < i) Len[i] = 1;
                else Len[i] = min(Len[(mxi<<1)-i], mxp - i + 1);
                while(1 <= i - Len[i] + 1 && i + Len[i] - 1 <= n && S[i-Len[i]+1] == S[i+Len[i]-1])
                    Len[i]++;
                Len[i]--;
                if(mxp < i + Len[i] - 1) mxi = i;
            }
            build(0, n, 1);
            update(0, n, 1, 0, -1);
            for(int i = 1; i <= n; i++) {
                int ql = i - Len[i], qr = n;
                int tmp = query(0, n, 1, ql, qr) + 1;
                if(tmp < f[i+Len[i]-1]) update(0, n, 1, i + Len[i] - 1, tmp);
            }
            printf("%d
    ", f[n]);
        }
         
        return 0;
    }
    
  • 相关阅读:
    DataPager 分页样式(css)
    Mysql日志详解
    Oracle 优化器
    [oracle]对象统计数据
    [oracle] analyze 和dbms_stats 的区别
    增加SAP HEAP大小
    Problems with SYSDBA/SYSOPER/INTERNAL connect
    Physical Standby Switchover_status Showing Not Allowed
    REHL8 oracle 19C RAC安装中的坑
    REHL8 oracle 19C RAC安装四(数据库创建)
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6389125.html
Copyright © 2011-2022 走看看