UVA 11468 Substring (+ AC automatic search memory chicken)

Portal

Meaning of the questions: to give you the K pattern string, then, give you n characters, and their probability of occurrence p [i], certainly by the given pattern string of characters.

   And all the characters, or numbers, either uppercase and lowercase letters. Ask you to generate a string of length L, does not contain any probability pattern string is.

Solution: memory search + AC automaton. To build a pattern string AC automaton, no Last [] and Val [], only one metch [].

   Whether maintenance at this point is the last character of a pattern string node, and if so, this point can not go.

   Then, the rest is from the root, just take the L-step, remember to memories of otherwise time-out.

   Remember array large enough to open, or wa afternoon.

   

#include <bits/stdc++.h>
#define LL long long
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define mem(i, j) memset(i, j, sizeof(i))
#define pb push_back
using namespace std;

const int N = 20 * 20 + 5, M = 105;
char op[2];
double tmp;
struct Trie {
    int a[N][M], tot, metch[N], Fail[N], vis[N][M], n;
    double p[N], dp[N][M];
    char ch[M];
    void init() {
        mem(a[0], 0); tot = 1; metch[0] = 0; mem(dp, 0); mem(p, 0); mem(vis, 0);
    }
    int get(char Q) {
        if(Q >= '0' && Q <= '9') return Q - '0' + 1;
        if(Q >= 'A' && Q <= 'Z') return Q - 'A' + 11;
        return Q - 'a' + 37;
    }
    void join(char s[]) {
        int now = 0; int len = strlen(s);
        rep(i, 0, len - 1) {
            int id = get(s[i]);
            if(!a[now][id]) {
                mem(a[tot], 0); metch[tot] = 0;
                a[now][id] = tot++;
            }
            now = a[now][id];
        }
        metch[now] = 1;
    }
    void getFail() {
        queue<int> Q; while(!Q.empty()) Q.pop();
        rep(i, 1, M - 1) {
            if(a[0][i]) {
                Q.push(a[0][i]); Fail[a[0][i]] = 0;
            }
        }
        while(!Q.empty()) {
            int now = Q.front(); Q.pop();
            rep(i, 1, M - 1) {
                int u = a[now][i];
                if(u == 0) a[now][i] = a[Fail[now]][i];
                else {
                    Q.push(u);
                    Fail[u] = a[Fail[now]][i];
                    metch[u] |=metch [the Fail [U]]; 
                } 
            } 
        } 
    } 
    Double DFS ( int now, int L) {
         IF (L!) return  1.0 ;
         IF (VIS [now] [L]) return DP [now] [L]; 
        VIS [now] [L] = . 1 ;
         Double & ANS = DP [now] [L]; 
        ANS = 0.0 ; 
        REP (I, . 1 , M - . 1 ) { /// enumerate all possible characters 
            IF (metch [A [! now] [I]]) { /// this node can go
                ans += p[i] * dfs(a[now][i], L - 1);
            }
        }
        return ans;
    }
    void scan() {
        scanf("%d", &n);
        rep(i, 1, n) {
            scanf("%s %lf", op, &tmp);
            int id = get(op[0]);
            p[id] = tmp;
        }
    }
    void print(int cas) {
        int L; scanf("%d", &L);
        printf("Case #%d: ", cas);
        printf("%.6f\n", dfs(0, L));
    }
};
Trie AC;
char b[25];
int main() {
    int _; scanf("%d", &_); int cas = 0;
    while(_--) {
        AC.init();
        int k; scanf("%d", &k);
        rep(i, 1, k) {
            scanf("%s", b); AC.join(b);
        }
        AC.getFail();
        AC.scan();
        AC.print(++cas);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Willems/p/12003847.html