zoukankan      html  css  js  c++  java
  • [洛谷P4081][USACO17DEC]Standing Out from the Herd

    题目大意:给你$n$个字符串,对每个字符串求出只在这个字符串中出现的字串的个数

    解:先建广义$SAM$,然后对每个点统计一下它的子树中是不是都是在同一个字符串中的,是的话,就把这个点标成这一个字符串,计算贡献

    卡点:

    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #define maxn 100010
    
    long long ans[maxn];
    namespace SAM {
    #define N (maxn << 1)
    	int R[N], fail[N], nxt[N][26];
    	int lst = 1, idx = 1, bel[N];
    
    	void append(int ch, int tg) {
    		int p = lst, np = lst = ++idx; R[np] = R[p] + 1, bel[np] = tg;
    		for (; p && !nxt[p][ch]; p = fail[p]) nxt[p][ch] = np;
    		if (!p) fail[np] = 1;
    		else {
    			int q = nxt[p][ch];
    			if (R[p] + 1 == R[q]) fail[np] = q;
    			else {
    				int nq = ++idx;
    				fail[nq] = fail[q], R[nq] = R[p] + 1, fail[q] = fail[np] = nq;
    				std::copy(nxt[q], nxt[q] + 26, nxt[nq]);
    				for (; p && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq;
    			}
    		}
    	}
    
    	int head[N], cnt;
    	struct Edge {
    		int to, nxt;
    	} e[N];
    	inline void addedge(int a, int b) {
    		e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    	}
    	void dfs(int u) {
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			dfs(v);
    			if (~bel[v]) {
    				if (!bel[u]) bel[u] = bel[v];
    				else if (bel[u] != bel[v]) bel[u] = -1;
    			} else bel[u] = -1;
    		}
    	}
    	void work() {
    		for (int i = 2; i <= idx; i++) addedge(fail[i], i);
    		dfs(1);
    		for (int i = 2; i <= idx; i++) if (bel[i] != -1) ans[bel[i]] += R[i] - R[fail[i]];
    	}
    #undef N
    }
    
    int n;
    char s[maxn];
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++) {
    		scanf("%s", s);
    		SAM::lst = 1;
    		for (register char *ch = s; *ch; ++ch) SAM::append(*ch - 'a', i);
    	}
    	SAM::work();
    	for (int i = 1; i <= n; i++) printf("%lld
    ", ans[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    负载均衡之加权轮询算法(转)
    go 指南学习笔记
    select限制之文件描述符限制
    select的限制
    select实现超时(套接字IO超时设置)
    如何在CentOS 8上安装Puppet
    如何在Ubuntu 20.04 / 18.04或更老版本中安装ifconfig
    关于Ubuntu的Apt安装与使用介绍
    如何在CentOS 8上安装Suricata?
    如何在Ubuntu 20.04上安装PHP Composer
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10163850.html
Copyright © 2011-2022 走看看