zoukankan      html  css  js  c++  java
  • DNA Sequence POJ

    DNA Sequence POJ - 2778

    又被poj教育了一晚上, ll 取膜会t就离谱, 淦

    题面

    传送门

    题解

    先看数据, m <= 10 且 |s| <= 10, n <= 2e9

    明显n是不可能线性了, 考虑字符串吧

    这么小的数据量, 要去想用 tire 存

    然后不出现这些串, 就是所求串在trie上没匹配

    既然要匹配每个串, 那直接trie变成Ac自动机吧

    然后无非就是在自动机上 next 乱走只要不走到字符串的 尾节点(或者当前失配能走到其他串的尾节点)

    就合法, 就变成了有多少长度为 n 的路径条数, 那就是矩阵快速幂了

    ~~t了一晚上, 吐了, ll取膜复杂度这么高的吗~

    struct Martrix { 
        int n, m;
    	vector<VI> ma;
        Martrix(int N = 0, int M = 0) : n(N), m(M) { ma.resize(N, VI(M)); }
        Martrix operator*(const Martrix& a) {
            Martrix ans(n, a.m);
            rep(i, 0, n - 1) rep(j, 0, a.m - 1) {
    			rep(k, 0, m - 1) ans.ma[i][j] = (ans.ma[i][j] + (ll)ma[i][k] * a.ma[k][j]) % mod;
    		}
            return ans;
        }
    };
    
    struct AC {
        static const int N = 2e2 + 5, M = 4; //字符串总长度, 字符范围
        int trie[N][M], fail[N], q[N], tot;
        bool tag[N];
        void init() {
            rep(i, 0, M - 1) trie[0][i] = 0;
            tot = tag[0] = 0;
        }
        int newnode() {
            fail[++tot] = 0; memset(trie[tot], 0, sizeof trie[tot]);
            tag[tot] = 0;  return tot;
        }
        int getCH(char c) { return c == 'A' ? 0 : c == 'C' ? 1 : c == 'G' ? 2 : 3; }
        void insert(char* s) {
            int p = 0;
            for (int i = 0, ch = getCH(s[i]); s[i]; p = trie[p][ch], ch = getCH(s[++i]))
                if (!trie[p][ch]) trie[p][ch] = newnode();
            tag[p] = 1;
        }
        void build() {
            int head = 0, tail = -1;
            rep (i, 0, M - 1) if (trie[0][i]) q[++tail] = trie[0][i];
            for (int p = q[head]; head <= tail; p = q[++head])
                rep (i, 0, M - 1)
                    if (trie[p][i])
                        fail[trie[p][i]] = trie[fail[p]][i], q[++tail] = trie[p][i], tag[trie[p][i]] |= tag[fail[trie[p][i]]];
                    else trie[p][i] = trie[fail[p]][i];
        }
    } ac;
    
    const int N = 4e1 + 5, M = 123 + 5;
    int n, m, _, k;
    char s[15];
    
    Martrix a, b;
    
    void getMartrix() {
        a = Martrix(ac.tot + 1, ac.tot + 1); b = Martrix(ac.tot + 1, 1);
        rep(i, 0, ac.tot) {
            if (!ac.tag[i]) 
                rep(j, 0, 3) 
                    if (!ac.tag[ac.trie[i][j]]) ++a.ma[i][ac.trie[i][j]];
            b.ma[i][0] = 1;
        }
    }
    
    Martrix qpow(Martrix a, ll b) {
        Martrix ans(a.n, a.m);
        rep(i, 0, a.n - 1) ans.ma[i][i] = 1;
        for (; b; b >>= 1, a = a * a)
            if (b & 1) ans = ans * a;
        return ans;
    }
    
    int main() {
        IOS; cin >> m >> n; ac.init();
        rep(i, 1, m) cin >> s, ac.insert(s);
        ac.build(); getMartrix();
        a = qpow(a, n) * b;
    	cout << a.ma[0][0];
        return 0;
    }
    
  • 相关阅读:
    UIImageView的动画效果(左右移动、旋转、缩放)
    图片点击放大,再次点击回到原来状态(图片缩放)
    设置一个视图控制器为底部视图的方法
    Pods written in Swift can only be integrated as frameworks; add `use_frameworks!` to your Podfile or target to opt into using it. The Swift Pods being used are: ReactiveCocoa, ReactiveSwift, and Resul
    cocoaPod的使用
    cocoaPod安装过程
    RAC(reactivecocoa)的使用方法
    百度地图定位
    <NET CLR via c# 第4版>笔记 第11章 事件
    <NET CLR via c# 第4版>笔记 第10章 属性
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14186741.html
Copyright © 2011-2022 走看看