zoukankan      html  css  js  c++  java
  • bzoj3790 神奇项链

    题目大意:

    你有两种机器,一种可以生产回文串,一种可以链接两个串。链接时可以覆盖相同前/后缀。

    给出多个串,求最少链接多少次。

    题解:
    先做manacher找出最长回文,然后贪心发现这是线段覆盖。

    排序然后搞就行了。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char s0[50050],s[100050];
    int len,n,p[100050];
    struct node
    {
        int l,r;
    }d[100050];
    void manacher()
    {
        int mid = 0,mx = 0;
        for(int i=1;i<=n;i++)
        {
            if(i<=mx)p[i]=min(p[2*mid-i],mx-i+1);
            else p[i]=1;
            while(s[i+p[i]]==s[i-p[i]])p[i]++;
            d[i].l=i-p[i]+1,d[i].r=i+p[i]-1;
            if(i+p[i]-1>mx)
            {
                mid=i;
                mx=i+p[i]-1;
            }
        }
    }
    bool cmp(node a,node b)
    {
        if(a.l!=b.l)return a.l<b.l;
        return a.r<b.r;
    }
    int main()
    {
        while(scanf("%s",s0+1)>0)
        {
            len = strlen(s0+1);
            s[0]='!',n=0;
            for(int i=1;i<=len;i++)
            {
                s[++n]='#';
                s[++n]=s0[i];
            }
            s[++n]='#',s[n+1]='@';
            manacher();
            sort(d+1,d+n+1,cmp);
            int cnt = 0,now = 0,mxr=0;
            for(int i=1;i<=n&&now!=n;)
            {
                mxr=0;
                while(d[i].l<=now+1)mxr=max(mxr,d[i].r),i++;
                i--;
                cnt++;
                now=mxr;
            }
            printf("%d
    ",cnt-1);
        }
        return 0;
    }
  • 相关阅读:
    JavaScript高级-----8.函数进阶(2)
    JavaScript高级-----7.函数进阶(1)
    2014-10-18 来美半个月
    修手机记
    圆梦美利坚之三:租房记
    圆梦美利坚之二:买机票记
    Hadoop 停止Job
    IIS应用程序池数目
    HTML5 microdata
    Java sql helper[转]
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10014603.html
Copyright © 2011-2022 走看看