zoukankan      html  css  js  c++  java
  • day16T2改错记

    题目描述

    给出(n)个串,你要从每个串中抽出一个子串(可以是空串),把他们拼接起来,问:

    1. 按字典序输出所有可能的结果(包括空串)
    2. 输出总共有多少种不同的结果(包括空串),对(1e9+7)取模

    最后输入一个(k),为(0)时只回答第二问,为(1)时回答两个问

    保证输入不超过(1MB),输出不超过(200MB)(就是说第二问真实值很大时不会要求回答第一问)

    解析

    要取出子串,容易想到后缀自动机

    于是对每个串建出后缀自动机

    然后考虑怎么表示“拼接”

    不难发现,如果后面某个串中存在的字符可以在当前这个自动机内转移到,那么取后者不会漏掉任何结果,所以我们只用管每个节点在自己的自动机内转移不到的字符

    即只有当不能在自己的串中转移时才考虑拼接后面的串

    假设某个节点(u)没有转移到(c)的边,那么我们找到它后面的自动机中第一个能转移到(c)的根节点(rt),从(u)(rt->trans[c])拉一条边,这样就表示了“拼接”的过程

    第一问就从第一个串的根节点开始贪心地(dfs),过程中输出即可,此处可以信仰一波不会(TLE),不然光输出就(GG)了,想来不会有这种数据……

    第二问就是问路径数了,拓扑排序(dp)即可

    代码

    为什么贴的是(70pts)代码呢?因为有(3)组数据输出实在太长,(OJ)判了所有人(OLE)……

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define MAXN 1000005
    
    typedef long long LL;
    const int mod = (int)1e9 + 7;
    const char set[] = {'A', 'C', 'G', 'T'};
    struct SAM {
    	int idx, cnt, last, root[MAXN], next[MAXN << 1][4], link[MAXN << 1], maxlen[MAXN << 1], deg[MAXN << 1], top, dp[MAXN << 1];
    	bool vis[MAXN << 1]; char cur[MAXN << 1];
    	int newnode(int = 0);
    	int add(int);
    	void insert(char *);
    	void prework();
    	void prework(int, int);
    	void dfs(int);
    	void bfs();
    };
    
    int N, K;
    char str[MAXN];
    SAM sam;
    int ans;
    
    inline void inc(int &x, int y) { x += y; if (x >= mod) x -= mod; }
    inline void dec(int &x, int y) { x -= y; if (x < 0) x += mod; }
    inline int add(int x, int y) { x += y; return x >= mod ? x - mod : x; }
    inline int sub(int x, int y) { x -= y; return x < 0 ? x + mod : x; }
    
    int main() {
    	freopen("copy.in", "r", stdin);
    	freopen("copy.out", "w", stdout);
    
    	scanf("%d", &N);
    	for (int i = 1; i <= N; ++i) {
    		scanf("%s", str);
    		sam.insert(str);
    	}
    	scanf("%d", &K);
    	sam.prework();
    	if (K) sam.dfs(sam.root[1]);
    	sam.bfs();
    	printf("%d
    ", ans);
    
    	return 0;
    }
    int SAM::newnode(int x) {
    	++idx;
    	if (x) {
    		link[idx] = link[x], maxlen[idx] = maxlen[x];
    		for (int i = 0; i < 4; ++i) next[idx][i] = next[x][i];
    	}
    	return idx;
    }
    int SAM::add(int c) {
    	int np = newnode(), p = last;
    	maxlen[np] = maxlen[last] + 1;
    	while (p && !next[p][c]) next[p][c] = np, p = link[p];
    	if (!p) link[np] = root[cnt];
    	else {
    		int q = next[p][c];
    		if (maxlen[q] == maxlen[p] + 1) link[np] = q;
    		else {
    			int nq = newnode(q);
    			maxlen[nq] = maxlen[p] + 1;
    			link[q] = link[np] = nq;
    			while (p && next[p][c] == q) next[p][c] = nq, p = link[p];
    		}
    	}
    	return np;
    }
    void SAM::insert(char *s) {
    	int n = strlen(s); last = root[++cnt] = newnode();
    	for (int i = 0; i < n; ++i) last = add(std::lower_bound(set, set + 4, s[i]) - set);
    }
    void SAM::prework() {
    	for (int i = cnt; i; --i) prework(root[i], root[i + 1]);
    	for (int i = 1; i <= idx; ++i) for (int j = 0; j < 4; ++j) ++deg[next[i][j]];
    	for (int i = 2; i <= cnt; ++i) for (int j = 0; j < 4; ++j) --deg[next[root[i]][j]];
    }
    void SAM::prework(int x, int y) {
    	if (vis[x]) return;
    	vis[x] = 1;
    	for (int i = 0; i < 4; ++i)
    		if (!next[x][i]) next[x][i] = next[y][i];
    		else prework(next[x][i], y);
    }
    void SAM::dfs(int x) {
    	cur[top] = '';
    	printf("%s
    ", cur);
    	for (int i = 0; i < 4; ++i)
    		if (next[x][i]) {
    			cur[top++] = set[i];
    			dfs(next[x][i]);
    			--top;
    		}
    }
    void SAM::bfs() {
    	static int q[MAXN << 1], hd, tl;
    	q[tl++] = root[1], dp[root[1]] = 1;
    	while (hd < tl) {
    		int p = q[hd++];
    		if (!p) continue;
    		inc(ans, dp[p]);
    		for (int i = 0; i < 4; ++i) {
    			inc(dp[next[p][i]], dp[p]);
    			if (!(--deg[next[p][i]])) q[tl++] = next[p][i];
    		}
    	}
    }
    //Rhein_E 70pts
    
  • 相关阅读:
    美团面试,360面试 ,滴滴面试,阿里面试,百度面试,京东面试,搜狗面试:
    Maven 3-Maven依赖版本冲突的分析及解决小结 (阿里,美团,京东面试)
    maven snapshot和release版本的区别
    Maven 生命周期 和插件
    Maven pom 文件解释
    Zookeeper原理架构
    sublime 支持PHP语法提示
    Zen Coding 用法
    让浏览器屏蔽js
    淘宝设计师入门:设计师SDK环境配置
  • 原文地址:https://www.cnblogs.com/Rhein-E/p/10560540.html
Copyright © 2011-2022 走看看