• bzoj2351 2462


    我没写hash,写了一些奇怪的做法,好像被hash随便操了……

    如果没有多测,那么这道题是白书上的例题

    把询问矩阵当作a个模板串,建成一个ac自动机

    把一开始的矩阵当作n个串放到自动机上匹配,找到a个模板串所有出现的位置

    然后找到对应矩阵的左上角上计数(即如果是第i个模板串出现在第x个串的第y个位置,则g[x-i+1,y-b+1]++)

    然后判断是否有能接收a个模板串的左上角即可

    加了一些剪枝过了2462……

    然后2351无限TLE……

    要来数据发现,当a=4 b=5的那个点跑了好长时间

    有什么做法可以在a非常小的时候快速出解呢?(我就是不想写hash……)

    由于询问的a,b都是一定的,我们可以把a行的矩阵压成一个串,每一列压成一个二进制位即可

    这样就是给定n-a+1个长度为m的串,问一个长度为b的串是否是其中一个串的子串

    这……后缀自动机随便做,这个点就跑得飞快了(因为这样复杂度是O(2^a*n*m+q*a*b了)

    注意一下内存……

    附上猥琐的代码

      1 type node=record
      2        po,next:longint;
      3      end;
      4 
      5 var trie,po:array[0..50010,'0'..'1'] of longint;
      6     go:array[0..1500010,0..15] of longint;
      7     w,f:array[0..1500010] of longint;
      8     p,q:array[0..50010] of longint;
      9     g,v:array[0..1010,0..1010] of longint;
     10     e:array[0..1010] of node;
     11     te,last,n,m,a,b,len,ans,i,j,t,tot,k,l:longint;
     12     c:array[0..1010] of ansistring;
     13     s:ansistring;
     14     ch:char;
     15 
     16 procedure add(x,y:longint);
     17   begin
     18     inc(len);
     19     e[len].po:=y;
     20     e[len].next:=p[x];
     21     p[x]:=len;
     22   end;
     23 
     24 procedure fill(x0,y0,x:longint);
     25   var i,y,xx,yy:longint;
     26   begin
     27     i:=p[x];
     28     while i<>0 do
     29     begin
     30       y:=e[i].po;
     31       xx:=x0-y+1;
     32       yy:=y0-b+1;
     33       if xx>0 then
     34       begin
     35         if v[xx,yy]<>te then
     36         begin
     37           v[xx,yy]:=te;
     38           g[xx,yy]:=0;
     39         end;
     40         inc(g[xx,yy]);
     41         if g[xx,yy]>ans then ans:=g[xx,yy];
     42         if ans=a then exit;
     43       end;
     44       i:=e[i].next;
     45     end;
     46   end;
     47 
     48 procedure ac;
     49   var j,h,r,x,y:longint;
     50       c:char;
     51   begin
     52     h:=1;
     53     r:=0;
     54     for c:='0' to '1' do
     55       if trie[0,c]>0 then
     56       begin
     57         inc(r);
     58         q[r]:=trie[0,c];
     59         f[trie[0,c]]:=0;
     60       end;
     61 
     62     while h<=r do
     63     begin
     64       x:=q[h];
     65       for c:='0' to '1' do
     66         if trie[x,c]>0 then
     67         begin
     68           y:=trie[x,c];
     69           inc(r);
     70           q[r]:=y;
     71           j:=f[x];
     72           while (j>0) and (trie[j,c]=0) do j:=f[j];
     73           f[y]:=trie[j,c];
     74         end;
     75       inc(h);
     76     end;
     77   end;
     78 
     79 procedure change(c:longint);
     80   var q,p,np:longint;
     81   begin
     82     p:=go[last,c];
     83     if w[p]=w[last]+1 then last:=p
     84     else begin
     85       inc(t); np:=t;
     86       w[np]:=w[last]+1;
     87       go[np]:=go[p];
     88       f[np]:=f[p];
     89       f[p]:=np;
     90       q:=last;
     91       while go[q,c]=p do
     92       begin
     93         go[q,c]:=np;
     94         q:=f[q];
     95       end;
     96       last:=np;
     97     end;
     98   end;
     99 
    100 procedure ins(c:longint);
    101   var np,nq,p,q:longint;
    102   begin
    103     p:=last;
    104     inc(t); last:=t; np:=t;
    105     w[np]:=w[p]+1;
    106     while (p<>0) and (go[p,c]=0) do
    107     begin
    108       go[p,c]:=np;
    109       p:=f[p];
    110     end;
    111     if p=0 then f[np]:=1
    112     else begin
    113       q:=go[p,c];
    114       if w[q]=w[p]+1 then f[np]:=q
    115       else begin
    116         inc(t); nq:=t;
    117         w[nq]:=w[p]+1;
    118         go[nq]:=go[q];
    119         f[nq]:=f[q];
    120         f[q]:=nq; f[np]:=nq;
    121         while go[p,c]=q do
    122         begin
    123           go[p,c]:=nq;
    124           p:=f[p];
    125         end;
    126       end;
    127     end;
    128   end;
    129 
    130 procedure make(l,r,m:longint);
    131   var i,j:longint;
    132   begin
    133     for j:=1 to m do
    134     begin
    135       p[j]:=0;
    136       for i:=l to r do
    137         p[j]:=p[j]+g[i,j]*(1 shl (i-l));
    138     end;
    139   end;
    140 
    141 begin
    142   readln(n,m,a,b);
    143   if a>4 then
    144   begin
    145     for i:=1 to n do
    146       readln(c[i]);
    147     readln(te);
    148     while te>0 do
    149     begin
    150       dec(te);
    151       j:=0;
    152       trie[0,'1']:=0;
    153       trie[0,'0']:=0;
    154       t:=0;
    155       len:=0;
    156       for i:=1 to a do
    157       begin
    158         readln(s);
    159         j:=0;
    160         for k:=1 to b do
    161         begin
    162           if trie[j,s[k]]=0 then
    163           begin
    164             inc(t); p[t]:=0; w[t]:=k;
    165             trie[t,'0']:=0; trie[t,'1']:=0;
    166             trie[j,s[k]]:=t;
    167           end;
    168           j:=trie[j,s[k]];
    169         end;
    170         add(j,i);
    171       end;
    172       ac;
    173       for i:=0 to t do
    174         for ch:='0' to '1' do
    175         begin
    176           j:=i;
    177           while (j>0) and (trie[j,ch]=0) do j:=f[j];
    178           j:=trie[j,ch];
    179           po[i,ch]:=j;
    180         end;
    181 
    182       ans:=0;
    183       for i:=1 to n do
    184       begin
    185         j:=0;
    186         for k:=1 to m do
    187         begin
    188           if not((c[i][k]>='0') and (c[i][k]<='1')) then break;
    189           if b-w[j]>m-k+1 then break;
    190           j:=po[j,c[i][k]];
    191           if p[j]<>0 then
    192           begin
    193             fill(i,k,j);
    194             if ans=a then break;
    195           end;
    196         end;
    197         if (ans=a) or (n-i+ans<a) then break;
    198       end;
    199       writeln(ans div a);
    200     end;
    201   end
    202   else begin
    203     t:=1;
    204     for i:=1 to n do
    205     begin
    206       for j:=1 to m do
    207       begin
    208         read(ch);
    209         g[i,j]:=ord(ch)-48;
    210       end;
    211       readln;
    212     end;
    213     for i:=1 to n-a+1 do
    214     begin
    215       make(i,i+a-1,m);
    216       last:=1;
    217       for j:=1 to m do
    218         if go[last,p[j]]<>0 then change(p[j])
    219         else ins(p[j]);
    220     end;
    221     readln(te);
    222     while te>0 do
    223     begin
    224       dec(te);
    225       for i:=1 to a do
    226       begin
    227         for j:=1 to b do
    228         begin
    229           read(ch);
    230           g[i,j]:=ord(ch)-48;
    231         end;
    232         readln;
    233       end;
    234       make(1,a,b);
    235       j:=1;
    236       ans:=1;
    237       for i:=1 to b do
    238         if go[j,p[i]]=0 then
    239         begin
    240           ans:=0;
    241           break;
    242         end
    243         else j:=go[j,p[i]];
    244       writeln(ans);
    245     end;
    246   end;
    247 end.
    View Code
  • 相关阅读:
    分块的一些题(入门)
    HH的项链
    2019 CCPC-Wannafly Winter Camp Div2 Day1
    2019 CCPC-Wannafly Winter Camp Div2 Day7
    HDU-5672 String(尺取)
    POJ-3104 Drying(二分
    Codeforces
    Java把内存划分为4个部分 1. 代码区 1、栈区 3、堆区 4、静态区域
    二:java语法基础:
    一:java概述:
  • 原文地址:https://www.cnblogs.com/phile/p/4593319.html
Copyright © 2020-2023  润新知