zoukankan      html  css  js  c++  java
  • Codeforces 235C Cyclical Quest

    题目大意

          给你一个原始串s,接下来n个询问,每次询问给出一个字符串,问原始串中有多少子串是给出字符串的循环同构串。

    题解

          对于原始串s建立sam,求出sam每个节点right集合的大小。对于每个询问,把询问串最小循环节-1复制一份拼在询问串的后面然后在sam上走。如果匹配长度超过length(询问串),这时候需要跳到parent的树上这个节点祖先中第一个节点的dis大于length的地方(因为直接加我wa了一发),再ans+=当前节点right集合的大小。

      1 program j01;
      2 const maxn=3000086;mxn=200086;
      3 type node=record son:array['a'..'z']of longint;fa,dis:longint; end;
      4 var s:ansistring;
      5     t:array[0..maxn]of node;
      6     ch:array[0..mxn]of char;
      7     sum,tmp,r:array[0..maxn]of longint;
      8     i,tt,n,len,last,root,ans,len2:longint;
      9     next:array[0..mxn]of longint;
     10 
     11 function newnode(d:longint):longint;
     12 begin
     13   inc(tt);t[tt].dis:=d;exit(tt);
     14 end;
     15 
     16 procedure ins(ch:char);
     17 var p,np,q,nq:longint;i:char;
     18 begin
     19   p:=last;np:=newnode(t[p].dis+1);last:=np;
     20   r[np]:=1;
     21   while(t[p].son[ch]=0)and(p>0) do
     22   begin
     23     t[p].son[ch]:=np;p:=t[p].fa;
     24   end;
     25   if p=0 then t[np].fa:=root else
     26   begin
     27     q:=t[p].son[ch];
     28     if t[q].dis=t[p].dis+1 then t[np].fa:=q else
     29     begin
     30       nq:=newnode(t[p].dis+1);
     31       for i:='a' to 'z' do t[nq].son[i]:=t[q].son[i];
     32       t[nq].fa:=t[q].fa;
     33       t[q].fa:=nq;t[np].fa:=nq;
     34       while t[p].son[ch]=q do
     35       begin
     36         t[p].son[ch]:=nq;p:=t[p].fa;
     37       end;
     38     end;
     39   end;
     40 end;
     41 
     42 procedure build;
     43 var i,p:longint;
     44 begin
     45   last:=1;root:=1;tt:=1;len:=length(s);
     46   for i:=1 to len do ins(s[i]);
     47   fillchar(sum,sizeof(sum),0);
     48   for i:=1 to tt do inc(sum[t[i].dis]);
     49   for i:=1 to len do inc(sum[i],sum[i-1]);
     50   for i:=tt downto 1 do
     51   begin
     52     tmp[sum[t[i].dis]]:=i;dec(sum[t[i].dis]);
     53   end;
     54   for i:=tt downto 1 do
     55   begin
     56     p:=tmp[i];inc(r[t[p].fa],r[p]);
     57   end;
     58 end;
     59 
     60 procedure getnext;
     61 var i,j:longint;
     62 begin
     63   next[1]:=0;j:=0;len:=length(s);
     64   for i:=2 to len do
     65   begin
     66     while(j>0)and(s[j+1]<>s[i])do j:=next[j];
     67     if s[j+1]=s[i] then inc(j);
     68     next[i]:=j;
     69   end;
     70 end;
     71 
     72 procedure getch;
     73 var x,i:longint;
     74 begin
     75   for i:=1 to len do ch[i]:=s[i];
     76   x:=len-next[len];
     77   if (x=0)or(len mod x<>0) then x:=len;
     78   dec(x);
     79   for i:=len+1 to len+x do ch[i]:=s[i-len];
     80   len2:=len+x;
     81 end;
     82 
     83 procedure work;
     84 var j:char;i,dis,p:longint;
     85 begin
     86   p:=root;dis:=0;
     87   for i:=1 to len2 do
     88   begin
     89     j:=ch[i];
     90     if t[p].son[j]>0 then
     91     begin
     92       p:=t[p].son[j];inc(dis);
     93     end else
     94     begin
     95       while(p>0)and(t[p].son[j]=0)do p:=t[p].fa;
     96       if p=0 then
     97       begin
     98         p:=root;dis:=0;
     99       end else
    100       begin
    101         dis:=t[p].dis+1;p:=t[p].son[j];
    102       end;
    103     end;
    104     while t[t[p].fa].dis>=len do
    105     begin
    106       p:=t[p].fa;dis:=t[p].dis;
    107     end;
    108     if dis>=len then inc(ans,r[p]);
    109   end;
    110 end;
    111 
    112 begin
    113   readln(s);
    114   build;
    115   readln(n);
    116   for i:=1 to n do
    117   begin
    118     readln(s);
    119     getnext;getch;
    120     ans:=0;work;
    121     writeln(ans);
    122   end;
    123 end.
    View Code
  • 相关阅读:
    从0开始搭建Element项目
    Git的上传步骤
    从JVM的角度解析String
    两个字符串相加究竟发生了什么
    简单工厂搭配策略模式
    java返回集合为null还是空集合
    idea常用快捷键
    (7)Stream简介
    (6)函数式接口的简单使用
    (4)函数式接口
  • 原文地址:https://www.cnblogs.com/oldjang/p/6748154.html
Copyright © 2011-2022 走看看