zoukankan      html  css  js  c++  java
  • Ctsc2012 Cheat

    题目描述

    题解:

    看起来是个dp。

    还需要SAM维护。

    还需要单调队列优化。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define S 1100050
    int n,m;
    char s[S];
    struct node
    {
        int pre,len,trs[2];
    }p[2*S];
    struct SAM
    {
        int tot,las;
        SAM(){tot=las=1;}
        void res(){las=1;}
        void insert(int c)
        {
            int np,nq,lp,lq;
            np=++tot;
            p[np].len = p[las].len +1;
            for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre)
                p[lp].trs[c]=np;
            if(!lp)p[np].pre = 1;
            else
            {
                lq = p[lp].trs[c];
                if(p[lq].len==p[lp].len+1)p[np].pre = lq;
                else
                {
                    nq = ++tot;
                    p[nq] = p[lq];
                    p[nq].len = p[lp].len+1;
                    p[lq].pre = p[np].pre = nq;
                    while(p[lp].trs[c]==lq)
                    {
                        p[lp].trs[c] = nq;
                        lp = p[lp].pre;
                    }
                }
            }
            las = np;
        }
    }sam;
    int len,dp[S],st[S],hd,tl,rgt[S],lim[S];
    void init()
    {
        len = strlen(s+1);
        int now = 1,u = 1,cnt = 0;
        for(int i=1;i<=len;i++)
        {
            int c = s[i]-'0';
            if(p[u].trs[c])
            {
                u = p[u].trs[c];
                cnt++;
            }else
            {
                while(u&&!p[u].trs[c])
                {
                    now+=cnt-p[p[u].pre].len;
                    u=p[u].pre;cnt = p[u].len;
                }
                if(!u)
                {
                    u=1;
                    now=i+1;
                    cnt=0;
                }else
                {
                    cnt++;
                    u = p[u].trs[c];
                }
            }
            lim[i]=now;
        }
    }
    bool check(int k)
    {
        hd=1,tl=0;
        dp[0]=0;
        for(int i=1;i<=len;i++)
        {
            dp[i] = dp[i-1];
            if(i-k>=0)
            {
                while(hd<=tl&&dp[i-k]-(i-k)>dp[st[tl]]-st[tl])
                    tl--;
                   st[++tl]=i-k;
               }
            while(hd<=tl&&st[hd]+1<lim[i])
                hd++;
            if(hd<=tl)
                dp[i] = max(dp[i],dp[st[hd]]+i-st[hd]);
        }
        return (double)dp[len]-(double)len*0.9>=-1.0*1e-6;
    }
    int div()
    {
        int l=0,r=len,ans=0;
        while(l<=r)
        {
            int mid = (l+r)>>1;
            if(check(mid))
            {
                ans = mid;
                l = mid+1;
            }else
            {
                r = mid-1;
            }
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++)
        {
            sam.res();
            scanf("%s",s+1);
            int len = strlen(s+1);
            for(int j=1;j<=len;j++)
                sam.insert(s[j]-'0');
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s+1);
            init();
            printf("%d
    ",div());
        }
        return 0;
    }
    
  • 相关阅读:
    Keil(MDK) 5 软件安装教程
    JPA 的specification动态查询
    idea 建立JPA项目(二)
    HBase单节点的安装与配置
    【codevs3012+codevs3037】线段覆盖4+线段覆盖5(DP)
    MySQL下载和安装教程
    二、单线程的 JavaScript
    #JS 基础之异步(一)
    JS 基础之: 继承的 六 种实现方式
    源码浅析-Vue3中的13个全局Api
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10122651.html
Copyright © 2011-2022 走看看