zoukankan      html  css  js  c++  java
  • BZOJ2806: [Ctsc2012]Cheat(广义后缀自动机,单调队列优化Dp)

    Description

    Input

    第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库
    的行数
    接下来M行的01串,表示标准作文库
    接下来N行的01串,表示N篇作文

    Output

    N行,每行一个整数,表示这篇作文的Lo 值。

    Sample Input

    1 2
    10110
    000001110
    1011001100

    Sample Output

    4

    解题思路:

    L0值具有单调性。

    L0值为0时,一定有匹配,为1时只需要考虑字符集,为2时要考虑前后顺序,所以具有单调性,L0越小匹配长度越大,那么可以二分。

    这道题要求不能覆盖,所以不能使用简单的Dp来解决,但也很明显,得知一个字符串某一位为结尾时最长匹配长度是很有用的QAQ

    所以设f[i]为以文本串i结尾,最长可识别子串的长度,那么startpos就是i-f[i],设Dp[i]表示匹配到i最长(可以不连续,但不小于L0)的最大匹配长度。

    为了实现可不连续,Dp[i]初值为Dp[i-1],所以Dp[i]的转移方程就是Dp[i]=max(Dp[i-1],max({Dp[j]+i-j|i-j>=L0}))

    转移是O(n2)的过不了,可以将Dp[j]-j与i分离将Dp[j]-j用单调队列维护,就是O(n)的了^_^

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 struct sant{
      5     int tranc[26];
      6     int len;
      7     int pre;
      8 }s[2100000];
      9 int siz;
     10 int fin;
     11 int n,m;
     12 char tmp[2100000];
     13 int maxl[2100000];
     14 int dp[3000000];
     15 int x[2000000];
     16 void Insert(int c)
     17 {
     18     int nwp,nwq,lsp,lsq;
     19     nwp=++siz;
     20     s[nwp].len=s[fin].len+1;
     21     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
     22         s[lsp].tranc[c]=nwp;
     23     if(!lsp)
     24         s[nwp].pre=1;
     25     else{
     26         lsq=s[lsp].tranc[c];
     27         if(s[lsq].len==s[lsp].len+1)
     28             s[nwp].pre=lsq;
     29         else{
     30             nwq=++siz;
     31             s[nwq]=s[lsq];
     32             s[nwq].len=s[lsp].len+1;
     33             s[nwp].pre=s[lsq].pre=nwq;
     34             while(s[lsp].tranc[c]==lsq)
     35             {
     36                 s[lsp].tranc[c]=nwq;
     37                 lsp=s[lsp].pre;
     38             }
     39         }
     40     }
     41     fin=nwp;
     42     return ;
     43 }
     44 bool can(int L0,int len)
     45 {
     46     dp[0]=0;
     47     int t=0,h=1;
     48     for(int i=1;i<=len;i++)
     49     {
     50         dp[i]=dp[i-1];
     51         if(i<L0)
     52             continue;
     53         while(t>=h&&dp[x[t]]-x[t]<=dp[i-L0]-i+L0)t--;
     54         x[++t]=i-L0;
     55         while(t>=h&&x[h]<i-maxl[i])h++;
     56         if(t>=h)
     57             dp[i]=std::max(dp[x[h]]+i-x[h],dp[i]);
     58     }
     59     return 10*dp[len]>=9*len;
     60 }
     61 int main()
     62 {
     63     fin=++siz;
     64     scanf("%d%d",&n,&m);
     65     for(int i=1;i<=m;i++)
     66     {
     67         scanf("%s",tmp+1);
     68         int len=strlen(tmp+1);
     69         fin=1;
     70         for(int j=1;j<=len;j++)
     71             Insert(tmp[j]-'0');
     72     }
     73     while(n--)
     74     {
     75         scanf("%s",tmp+1);
     76         int len=strlen(tmp+1);
     77         int root=1;
     78         int mxl=0;
     79         for(int i=1;i<=len;i++)
     80         {
     81             int c=tmp[i]-'0';
     82             if(s[root].tranc[c])
     83             {
     84                 root=s[root].tranc[c];
     85                 mxl++;
     86             }else{
     87                 while(!s[root].tranc[c])
     88                     root=s[root].pre;
     89                 if(!root)
     90                 {
     91                     root=1;
     92                     mxl=0;
     93                 }else{
     94                     mxl=s[root].len+1;
     95                     root=s[root].tranc[c];
     96                 }
     97             }
     98             maxl[i]=mxl;
     99         }
    100         int ans=0;
    101         int l=0,r=len;
    102         while(l<=r)
    103         {
    104             int mid=(l+r)>>1;
    105             if(can(mid,len))
    106             {
    107                 ans=mid;
    108                 l=mid+1;
    109             }else
    110                 r=mid-1;
    111         }
    112         printf("%d
    ",ans);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    2017ccpc全国邀请赛(湖南湘潭) E. Partial Sum
    Codeforces Round #412 C. Success Rate (rated, Div. 2, base on VK Cup 2017 Round 3)
    2017 中国大学生程序设计竞赛 女生专场 Building Shops (hdu6024)
    51nod 1084 矩阵取数问题 V2
    Power收集
    红色的幻想乡
    Koishi Loves Segments
    Wood Processing
    整数对
    Room and Moor
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10046126.html
Copyright © 2011-2022 走看看