• [POJ1743]Musical Theme


    题目大意:
      给你一个数列,我们数列中两个串是相似的当且仅当这两个串的长度至少为5、两个串差分后形成的数列一样且不相交,求最长的相似串的长度。

    思路:
      后缀自动机求最长不相交重复子串。
      首先将差分后的数列构造SAM,然后按照拓扑序DP,得到每个状态right集合的最大值t与最小值s,表示当前状态对应的最长的不相交子串为[s,t]。
      然而我们还要保证以当前状态结尾的子串的长度能够与[s,t]子串相等,设当前状态对应的最长子串长度为len,则最长相似串的长度为min(t-s+1,len) 。
      然后取max即可。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<cstring>
     4 #include<algorithm>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int inf=0x7fffffff;
    13 const int LEN=20001;
    14 int n;
    15 class SuffixAutomaton {
    16     private:
    17         static const int SIGMA_SIZE=180;
    18         struct State {
    19             int link,go[SIGMA_SIZE],len,maxright,minright;
    20         };
    21         State s[LEN<<1];
    22         int sz,newState(const int l) {
    23             sz++;
    24             s[sz].len=l;
    25             s[sz].minright=inf;
    26             return sz;
    27         }
    28         int root,last;
    29         int cnt[LEN],top[LEN<<1];
    30         void tsort() {
    31             for(int i=1;i<=sz;i++) cnt[s[i].len]++;
    32             for(int i=n;i;i--) cnt[i-1]+=cnt[i];
    33             for(int i=1;i<=sz;i++) top[cnt[s[i].len]--]=i;
    34         }
    35     public:
    36         void reset() {
    37             sz=0;
    38             memset(s,0,sizeof s);
    39             root=last=newState(0);
    40             memset(cnt,0,sizeof cnt);
    41         }
    42         void extend(const int w) {
    43             int p=last,new_p=newState(s[last].len+1);
    44             s[new_p].maxright=s[new_p].minright=s[new_p].len;
    45             while(p&&!s[p].go[w]) {
    46                 s[p].go[w]=new_p;
    47                 p=s[p].link;
    48             }
    49             if(!p) {
    50                 s[new_p].link=root;
    51             } else {
    52                 int q=s[p].go[w];
    53                 if(s[q].len==s[p].len+1) {
    54                     s[new_p].link=q;
    55                 } else {
    56                     int new_q=newState(s[p].len+1);
    57                     memcpy(s[new_q].go,s[q].go,sizeof s[q].go);
    58                     s[new_q].link=s[q].link;
    59                     s[q].link=s[new_p].link=new_q;
    60                     while(p&&s[p].go[w]==q) {
    61                         s[p].go[w]=new_q;
    62                         p=s[p].link;
    63                     }
    64                 }
    65             }
    66             last=new_p;
    67         }
    68         int stat() {
    69             tsort();
    70             for(int i=1;i<=sz;i++) {
    71                 int p=top[i],q=s[top[i]].link;
    72                 s[q].maxright=std::max(s[q].maxright,s[p].maxright);
    73                 s[q].minright=std::min(s[q].minright,s[p].minright);
    74             }
    75             int ret=0;
    76             for(int i=1;i<=sz;i++) {
    77                 ret=std::max(ret,std::min(s[i].maxright-s[i].minright+1,s[i].len+1));
    78             }
    79             return ret>=5?ret:0;
    80         }
    81 };
    82 SuffixAutomaton sam;
    83 int s[LEN];
    84 int main() {
    85     for(;;) {
    86         n=getint();
    87         if(!n) return 0;
    88         sam.reset();
    89         for(int i=1;i<=n;i++) s[i]=getint();
    90         for(int i=1;i<n;i++) sam.extend(s[i]=s[i+1]-s[i]+88);
    91         printf("%d
    ",sam.stat());
    92     }
    93 } 
  • 相关阅读:
    一个access连接的处理
    小说
    web版的outlook和project的结合,再和sns 结合,形成组织之间的一个共享信息.还有更多应用
    今天研究了一下window pe
    IMX6ULL开发板文本编辑工具
    Create class and methods in x++
    Image in AX 2009
    IP and userId dislay in AX 2009 title
    helpless....
    about Posted & Unposted of button function
  • 原文地址:https://www.cnblogs.com/skylee03/p/7522785.html
Copyright © 2020-2023  润新知