Room Test 16: Special character string (AC automaton + dp + kmp)

T1:

A frog lost the protection of the lotus leaf.
 It is very confused, so they decided to change their genes, species will not allow themselves to be old in a sheltered. All
well known, frog gene was a DNA fragment with a genetic effect, we believe that this is only a fragment "A", "T",
"C", "G" composed of, for convenience, we consider only one strand of DNA.
 Frog is experienced, it knows that this chain length is n, and the known sequence of m kinds asylum effect,
it is desirable that each position of this chain are sheltered. Note that the effect can be sheltered sequence overlap, a
position sheltered if and only if it is at least a sequence comprising sheltered effect.
 Want to know how many frog species to meet the conditions of the chain, modulo 109 + 9.

To 100% of the data 1 <= n <= 1000,1 <= m <= 10, sheltered sequence length effect does not exceed 10

analysis:

Problems related to the plurality of character strings match, first consider the AC automaton.

Definition of DP [i] [j] [k] as Couchu length i, j at the AC node number of the automaton, counting backwards from the k-th position have not yet been covered (and uncovered left-most of).

AC automaton using the longest jump fail pretreatment sheltered length of each node contains, when it is judged that the transfer is greater than the length of the cover equal to k + 1 (k comprises a point), it is possible to cover the description k, transferred to dp [i + 1] [son] [0] (son is the son of the current node)

Otherwise it proceeds to dp [i + 1] [son] [k + 1] k + 1 is more because this node is not covered.

#include<bits/stdc++.h>
using namespace std;
#define N 105
#define ri register int
const int mod=1e9+9;
int ndnum=0,ed[N],go[N][5],r[N],fail[N],dp[1005][N][12],n,m;
char s[15];
void add()
{
    int len=strlen(s+1),now=0;
    for(ri i=1;i<=len;++i){
        int c=r[(int)s[i]];//printf("%d\n",c);
        if(!go[now][c]) go[now][c]=++ndnum;
        now=go[now][c];
    }
    ed[now]=len;
}
void get_fail()
{
    queue<int> q;
    for(ri i=0;i<=3;++i) if(go[0][i]) q.push(go[0][i]);
    while(!q.empty()){
        int now=q.front(); q.pop();//printf("now:%d\n",now);
        for(ri i=0;i<=3;++i){
            if(!go[now][i]) go[now][i]=go[fail[now]][i];
            else{
                fail[go[now][i]]=go[fail[now]][i];
                q.push(go[now][i]);
                ED [Go [now] [I]] = max (ED [Go [now] [I]], ED [fail [Go [now] [I]]]);
                 // obtained by simultaneous pointer fail to seek the end point of the longest length to cover 
            }
        }
    }
}
void work()
{
    DP [ 0 ] [ 0 ] [ 0 ] = . 1 ;
     for (RI = I 0 ; I <n-; ++ I)
      for (RI J = 0 ; J <= ndnum; J ++) // 0 is the root node 
      for (RI K = 0 ; K <= . 9 ; K ++) { // . 9 due to be transferred to. 1 + K   
          IF (DP [I] [J] [K]!) Continue ;
           for (P = RI 0 ; P <= . 3 ; ++ P) {
               int son = Go [J] [P]; // traverse the current node every son 
              IF (ED [son]> = K + . 1 ) DP [I +. 1 ] [Son] [ 0 ] = (DP [I + . 1 ] [Son] [ 0 ] + DP [I] [J] [K])% MOD;
             // If cover is shifted to be in the inverse of 0 is not covering otherwise add this to more than transfer that has not been covered by the K +. 1 
              the else DP [I + . 1 ] [Son] [K + . 1 ] = (DP [I + . 1 ] [Son] [K + . 1 ] + DP [I ] [J] [K])% MOD;
        }
    }
    int ans = 0 ;
    for (r i i = 0 ; i <= ndnum; ++ i) = ans (ANS + dp [n] [i] [ 0 ])% v;
    printf("%d\n",ans);
}
int main ()
{
    scanf("%d%d",&n,&m);
    r[(int)'A']=0; r[(int)'C']=1; r[(int)'G']=2; r[(int)'T']=3;
    for(ri i=1;i<=m;++i) scanf("%s",s+1),add();
    get_fail();
    work();
    return 0;
}
/*
6 2 
CAT 
TACT 
*/
View Code

 

T2:

 While obtaining asylum, the frog (or called something else species) also received a powerful force. Its
existence is beyond all the other creatures of the natural world, so it wants to push the boundaries, to master this force.
 It now has been an old book, and it has been translated to a length of a lower case letter is constituted of n
strings, now, that it wants to find a longest substring, such that both the substring of string prefix and suffix, and
and in the middle of the string through (i.e., appears in the suffix position before the non-through).
 Because the story needs, we ensure that there is such a substring meet the conditions.

To 100% of the data, n <= 10000000

analysis:

Kmp consideration nex array definition: nex [i] = j represents 1 ~ j and i-j + 1 ~ i match, and j max, which is the longest prefix with the same suffix.

But this question there is a limit: must there have been in the middle. If direct access nex [n], and a middle position condition is satisfied, then there will be nex [x] == nex [n].

If there is no such x, indicating the length should be reduced, how shrink it, jump nex! !

Had a length of 3, since the intermediate appeared not satisfied, so by shortening the length of the n-hop NEX, to find a shorter, satisfies intermediate appeared.

 

 

#include<bits/stdc++.h>
using namespace std;
#define ri register int
#define N 10000005
int nex[N],n;
char s[N];
bool vis[N];
void get_next()
{
    nex[0]=nex[1]=0;
    for(ri i=2,j=0;i<=n;++i){
        while(j>0 && s[i]!=s[j+1]) j=nex[j];
        if(s[i]==s[j+1]) j++;
        nex[i]=j;
        if(i!=n) vis[j]=true;
    }
    for(ri i=1;i<=n;++i)
    printf("%d ",nex[i]);
}
int main ()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    get_next();
    int now=n;
    while(!vis[nex[now]] && now>0) now=nex[now];
    printf("%d\n",nex[now]);
}
/*
Ababa bada baba
*/
View Code

T3:

This small animal found strength in the book, it almost achieved success, according to the contents of the book, it is still missing a pair of glasses.

So it found a 01 string, you want to find the material glasses. It is desirable to find the most 01 string
length sequence strings (i.e., does not require continuous), the sequences satisfying properties between post 01 (01010 ... or 10101 ...).
But before looking, want to test it now has the power, so it chose a contiguous range, these
intervals of 1, 1 becomes 0 becomes 0, and then where to find the longest among 01 sub-sequence delivery string.
Of course, it wants to properly use their power only once (but be sure to use), making this sequence string becomes the best
possible long.

Analysis :

通过画图,出多组数据分析可知,无论怎么翻转,每次对答案最多贡献2,所以只需要求出初始01串长,然后再+2即可(注意和n取min)

#include<bits/stdc++.h>
using namespace std;
#define N 500005
#define ri register int
char s[N];
int a[N],tmp[N],n;
int check(int l,int r)
{
    memcpy(tmp,a,sizeof(a));
    for(ri i=l;i<=r;++i) tmp[i]^=1;
    int cnt1=0,cnt2=0,need=0;
    for(ri i=1;i<=n;++i) if(tmp[i]==need) cnt1++,need^=1;
    need=1;
    for(ri i=1;i<=n;++i) if(tmp[i]==need) cnt2++,need^=1;
    return max(cnt1,cnt2);
}
int main()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    int ans=0;
    for(ri i=1;i<=n;++i) a[i]=s[i]-'0';
    printf("%d\n",min(check(0,0)+2,n));
}
/*
10000011

11000111100001010101

10010110011000001111
10101010101
*/
View Code

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11712558.html