• HihoCoder


    https://hihocoder.com/login

    模拟赛的时候强行迭代dp做的题,事实上是AC自动机的套路题,虽说迭代不用算法比较亲民,但是确实抠细节不太好写,当时也写了有一个小时,如果知道这是一道AC自动机的套路题的话,就好做多了

    将N + 1个模式串插入AC自动机之后,如果进入到末尾结点就在贡献处加上(1LL << M - i + 1) * 方案数的贡献,表示当前长度有多少种可能到达这个节点,同时到达了之后后面的所有节点都可以任选。

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <bitset>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x)  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x)  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double PI = acos(-1.0);
    const double eps = 1e-9;
    const int maxn = 2010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    char str[maxn];
    int nxt[maxn][26],tot,fail[maxn],ed[maxn],root;
    int newnode(){
        for(int i = 0 ; i < 2; i ++) nxt[tot][i] = -1;
        ed[tot++] = 0;
        return tot - 1;
    }
    void init(){
        tot = 0;
        root = newnode();
    }
    void insert(char *str){
        int p = root;
        for(int i = 0; str[i]; i ++){
            int id = str[i] - '0';
            if(nxt[p][id] == -1) nxt[p][id] = newnode();
            p = nxt[p][id];
        }
        ed[p] = 1;
    }
    void Build(){
        queue<int>Q;
        fail[root] = root;
        for(int i = 0;i < 2; i ++){
            if(~nxt[root][i]){
                fail[nxt[root][i]] = root;
                Q.push(nxt[root][i]);
            }else{
                nxt[root][i] = root;
            }
        }
        while(!Q.empty()){
            int u = Q.front(); Q.pop();
            for(int i = 0 ; i < 2; i ++){
                if(~nxt[u][i]){
                    fail[nxt[u][i]] = nxt[fail[u]][i];
                    ed[nxt[u][i]] |= ed[nxt[fail[u]][i]];
                    Q.push(nxt[u][i]);
                }else{
                    nxt[u][i] = nxt[fail[u]][i];
                }
            }
        }
    }
    LL dp[2][maxn];
    int main(){
        int T = read();
        while(T--){
            Sca2(N,M); init(); 
            scanf("%s",str); insert(str);
            for(int i = 0 ; i < N ; i ++){
                if(str[i] == '1') str[i] = '0';
                else str[i] = '1';
                insert(str);
                if(str[i] == '1') str[i] = '0';
                else str[i] = '1';
            }
            Build();
            LL ans = 0;
            dp[0][0] = 1;
            for(int i = 1 ; i <= M ; i ++){
                for(int j = 0 ; j < tot; j ++) dp[i & 1][j] = 0;
                for(int j = 0 ; j < tot; j ++){
                    if(ed[j]) continue;
                    for(int k = 0 ; k < 2; k ++){
                        if(ed[nxt[j][k]]){
                            ans += dp[i + 1 & 1][j] * (1LL << (M - i));
                        }else{
                            dp[i & 1][nxt[j][k]] += dp[i + 1 & 1][j];
                        }
                    }
                }
            }
            Prl(ans);
            for(int j = 0 ; j < tot; j ++) dp[0][j] = dp[1][j] = 0;
        }
        return 0; 
    }
  • 相关阅读:
    poj 1026 Cipher
    python中的global
    基于DL的文本分类综述
    K近邻算法学习
    聚类评价指标学习
    pytorch自动求导学习
    反向传播的推导
    二分搜索常用【转载】
    《Attention is all you need》论文学习
    5-28日|5-30日
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/11469819.html
Copyright © 2020-2023  润新知