码迷,mamicode.com
首页 > 其他好文 > 详细

[hdu 4622]Reincarnation

时间:2014-08-14 20:03:59      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   

这道题是妥妥的后缀自动机裸题

学了后缀自动机后,我居然感觉这尼玛果然还是后缀数组最难了有木有!

后缀自动机我的理解就是一个动态的存后缀的 AC 自动机

以为后缀的特殊性,我们可以在上一次插入的节点后直接插入新的节点,然后沿着 fail(pre) 指针把一些该更新的更新掉即可

果然是好写好用喵~

 

如何统计 [i..j] 的不同子串数呢?我们注意到每个节点 step 就是根到该节点的最长路径的长度

也就是以该节点结尾的后缀的最长长度

p->step-p->fail->step 就是节点 p 被插入后缀自动机后新增的以 p 为结尾的子串数量

这样一来题目就没有任何压力了有不有喵~

 

bubuko.com,布布扣
  1 #include <cstdio>
  2 #include <cstring>
  3 const int sizeOfString=2048;
  4 const int sizeOfMemory=1000000;
  5 const int sizeOfType=26;
  6 
  7 namespace IOspace
  8 {
  9     inline int getint()
 10     {
 11         register int num=0;
 12         register char ch;
 13         do ch=getchar(); while (ch<0 || ch>9);
 14         do num=num*10+ch-0, ch=getchar(); while (ch>=0 && ch<=9);
 15         return num;
 16     }
 17     inline void putint(int num, char ch=\n)
 18     {
 19         char stack[10];
 20         register int top=0;
 21         for ( ;num;num/=10) stack[++top]=num%10+0;
 22         for ( ;top;top--) putchar(stack[top]);
 23         if (ch) putchar(ch);
 24     }
 25 }
 26 namespace suffixAutomaton
 27 {
 28     struct node
 29     {
 30         int step;
 31         node * pre;
 32         node * ch[sizeOfType];
 33         inline int calc() {return pre?step-pre->step:0;}
 34     };
 35     int tot=0;
 36     node memory[sizeOfMemory], * port;
 37     node * dfa, * last;
 38     inline node * newnode(node * t)
 39     {
 40         node * newt=port++;
 41         newt->step=0;
 42         if (t) newt->pre=t->pre, t->pre=newt, memcpy(newt->ch, t->ch, sizeof t->ch);
 43         else newt->pre=NULL, memset(newt->ch, 0, sizeof newt->ch);
 44         return newt;
 45     }
 46     inline void clear() {tot=0; port=memory; dfa=newnode(NULL); dfa->pre=dfa; last=dfa;}
 47 
 48     inline int ord(char ch) {return ch-a;}
 49     inline void insert(int w)
 50     {
 51         node * p=last, * newp=newnode(NULL);
 52         newp->step=p->step+1;
 53 
 54         for ( ;p->ch[w]==NULL;p=p->pre) p->ch[w]=newp;
 55         if (p->ch[w]==newp)
 56             newp->pre=dfa, tot+=newp->calc();
 57         else
 58         {
 59             node * q=p->ch[w];
 60             if (p->step+1==q->step)
 61                 newp->pre=q, tot+=newp->calc();
 62             else
 63             {
 64                 tot-=p->calc()+q->calc();
 65                 node * newq=newnode(q);
 66                 newq->step=p->step+1;
 67                 newp->pre=newq;
 68                 tot+=p->calc()+q->calc()+newp->calc()+newq->calc();
 69                 for ( ;p->ch[w]==q;p=p->pre) p->ch[w]=newq;
 70             }
 71         }
 72 
 73         last=newp;
 74     }
 75 }
 76 
 77 int T, n;
 78 char s[sizeOfString];
 79 int ans[sizeOfString][sizeOfString];
 80 
 81 int main()
 82 {
 83     for (T=IOspace::getint();T;T--)
 84     {
 85         scanf("%s", s);
 86         int len=strlen(s);
 87         memset(ans, 0, sizeof ans);
 88         for (int i=0;i<len;i++)
 89         {
 90             suffixAutomaton::clear();
 91             for (int j=i;j<len;j++)
 92             {
 93                 suffixAutomaton::insert(suffixAutomaton::ord(s[j]));
 94                 ans[i][j]=suffixAutomaton::tot;
 95             }
 96         }
 97         n=IOspace::getint();
 98         for (int i=1;i<=n;i++)
 99         {
100             int l=IOspace::getint()-1, r=IOspace::getint()-1;
101             IOspace::putint(ans[l][r]);
102         }
103     }
104 
105     return 0;
106 }
本傻装B系列

 

[hdu 4622]Reincarnation,布布扣,bubuko.com

[hdu 4622]Reincarnation

标签:style   blog   http   color   os   io   for   ar   

原文地址:http://www.cnblogs.com/dyllalala/p/3913135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!