zoukankan      html  css  js  c++  java
  • BZOJ2806:[CTSC2012]Cheat

    Description

    Input

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

    Output

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

    Sample Input

    1 2
    10110
    000001110
    1011001100

    Sample Output

    4

    HINT

    输入文件不超过1100000字节

    注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%

    题解:

    用所有的作文库字符串建一个广义后缀自动机。

    对于每个询问,将其输入到后缀自动机中,求出每个前缀的最长匹配后缀。

    根据后缀自动机的性质,成功多匹配一个字符时,匹配长度加1;跳到pre时,匹配长度变为step。

    二分答案,利用单调队列求出当前限制下至少不能匹配多少个字符,检验是否可行。

    代码(P++注意):

      1 #include<bits/stdc++.h>
      2 #define begin {
      3 #define end }
      4 #define while while(
      5 #define if if(
      6 #define do )
      7 #define then )
      8 #define for for(
      9 #define fillchar(a,b,c) memset(a,c,b)
     10 #define writeln printf("
    ")
     11 #define write printf
     12 #define readln readl()
     13 #define inc(a) a++
     14 #define dec(a) a--
     15 #define exit(a) return a
     16 #define mod %
     17 #define div /
     18 #define shl <<
     19 #define shr >>
     20 #define extended long double
     21 #define longint int
     22 #define integer short
     23 #define int64 long long
     24 template<typename T> inline void read(T& a)
     25 begin
     26   T x=0,f=1; char ch=getchar();
     27   while(ch<'0')or(ch>'9')do
     28   begin
     29     if ch=='-' then f=-1; ch=getchar();
     30   end
     31   while(ch>='0')and(ch<='9')do
     32   begin
     33     x=x*10+ch-'0'; ch=getchar();
     34   end
     35   a=x*f;
     36 end
     37 inline void readl()
     38 begin
     39   char ch; ch=getchar();
     40   while ch!='
    ' do ch=getchar();
     41 end
     42 using namespace std;
     43 int le,i,ii,j,k,l,r,ll,rr,mid,n,nn,m,ans,pre[3000005],step[3000005],a[3000005][2],last,now,q[3000005],f[3000005],lb[3000005];
     44 char s[3000005];
     45 bool dp(int x)
     46 begin
     47   l=1; if x<=1 then begin r=1; f[0]=0; lb[1]=0; end else r=0;
     48   for int i=1;i<=le;i++ do
     49   begin
     50     f[i]=f[i-1]+1;
     51     while(l<=r)and(lb[l]<q[i])do inc(l);
     52     if l<=r then f[i]=min(f[i],f[lb[l]]);
     53     if i-x+1>=0 then
     54     begin
     55       while(l<=r)and(f[lb[r]]>=f[i-x+1])do dec(r);
     56       inc(r); lb[r]=i-x+1;
     57     end
     58   end
     59   if f[le]*10<=le then exit(1);
     60   exit(0);
     61 end
     62 int main()
     63 begin
     64   read(n); read(nn); pre[0]=-1;
     65   for ii=1;ii<=nn;ii++ do 
     66   begin
     67     scanf("%s",s+1); le=strlen(s+1);  last=0;
     68     for i=1;i<=le;i++ do
     69     begin
     70       inc(m); now=m; step[now]=step[last]+1;
     71       while(last!=-1)and(a[last][s[i]-'0']==0)do
     72       begin a[last][s[i]-'0']=now; last=pre[last]; end
     73       if last==-1 then begin pre[now]=0; last=now; continue; end
     74       if step[last]+1==step[a[last][s[i]-'0']] then
     75       begin pre[now]=a[last][s[i]-'0']; last=now; continue; end
     76       j=a[last][s[i]-'0'];
     77       inc(m); a[m][0]=a[j][0]; a[m][1]=a[j][1]; pre[m]=pre[j]; step[m]=step[last]+1;
     78       pre[j]=m; pre[now]=m;
     79       while last!=-1 do
     80       begin
     81         if a[last][s[i]-'0']==j then a[last][s[i]-'0']=m;else break;
     82         last=pre[last];
     83       end
     84       last=now;
     85     end
     86     for i=1;i<=le;i++ do s[i]='';
     87   end
     88   for ii=1;ii<=n;ii++ do
     89   begin
     90     scanf("%s",s+1); le=strlen(s+1);
     91     now=0; last=0;
     92     for i=1;i<=le;i++ do
     93     begin
     94       while(now!=-1)and(a[now][s[i]-'0']==0)do begin now=pre[now]; if now!=-1 then last=step[now] ; end
     95       if now==-1 then begin now=0; last=0; end else begin now=a[now][s[i]-'0']; inc(last); end
     96       q[i]=i-last;
     97     end
     98     ans=0; ll=1; rr=le;
     99     while ll<=rr do
    100     begin
    101       mid=(ll+rr)div 2;
    102       if dp(mid) then begin ans=mid; ll=mid+1; end
    103       else rr=mid-1;
    104     end
    105     write("%d",ans); writeln;
    106   end
    107 end
    View Code
  • 相关阅读:
    预览PDF【reactpdf】插件的使用(二)
    多叉merkletree的实现
    中国优秀的架构师是不是出现了严重断层?
    工程师的思维转变
    QCore/Library说明文档
    QParserGenerator代码分析二(A fix&An example)
    山寨STL实现之list
    山寨STL实现笔记
    山寨STL实现之内存池V2
    词法分析器1(正则表达式到εNFA的转换)
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6495477.html
Copyright © 2011-2022 走看看