• 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;
    }
    
  • 相关阅读:
    python的函数修饰符(装饰器)
    hdu1175连连看(dfs+细节)
    hdu2553N皇后问题(dfs,八皇后)
    hdu1045Fire Net(经典dfs)
    hdu1050Moving Tables(贪心)
    hdu2037今年暑假不AC(贪心,活动安排问题)
    hdu1052Tian Ji -- The Horse Racing(贪心,细节多)
    hdu1009FatMouse' Trade(贪心)
    hdu1455Sticks(经典dfs+剪枝)
    hdu2509Be the Winner(反nim博弈)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10122651.html
Copyright © 2020-2023  润新知