zoukankan      html  css  js  c++  java
  • P4081 [USACO17DEC]Standing Out from the Herd P [广义SAM]

    我们直接把重复的部分去掉。

    (sum len_i - len_{fa_i})

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5 + 62;
    char s[maxn], str[maxn];
    int tot = 0 ;
    long long Ans[maxn] ;
    
    struct SAM {
    	int ch[maxn][26], cnt, len[maxn], fa[maxn];
    
    	SAM() {
    		cnt = 1;
    	}
    
    	int ins(int c, int las) {
    		int p = las, np = ++cnt;
    		len[np] = len[p] + 1;
    		for (; p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
    		if (!p) {
    			fa[np] = 1;
    		} else {
    			int q = ch[p][c];
    			if (len[q] == len[p] + 1) {
    				fa[np] = q;
    			} else {
    				int nq = ++cnt;
    				memcpy(ch[nq], ch[q], sizeof(ch[q]));
    				fa[nq] = fa[q], fa[q] = fa[np] = nq, len[nq] = len[p] + 1;
    				for (; p && ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
    			}
    		}
    		return np;
    	}
    	
    	int id[maxn] ;
    	
    	void col(int x , int c) {
    		for( ; x && id[x] ^ c && ~ id[x] ; x = fa[x])
    			id[x] = (id[x]) ? -1 : c ;
    	}
    	
    	void calc() {
    		int c = 1 , p = 1 ;
    		for(int i = 1 ; i <= tot ; i ++) {
    			if(! isspace(str[i])) {
    				col(p = ch[p][str[i] - 'a'] , c) ;
    			}
    			else {
    				p = 1 , ++ c ;
    			}
    		}
    		for(int i = 1 ; i <= cnt ; i ++) {
    			if(~ id[i]) {
    				Ans[id[i]] += len[i] - len[fa[i]] ;
    			}
    		}
    	}
    } sam;
    
    struct Trie {
    	int ch[maxn][26], cnt, qwq[maxn], fa[maxn];
    
    	Trie() {
    		cnt = 1;
    	}
    
    	void ins(int len) {
    		int p = 1;
    		for (int i = 1; i <= len; i++) {
    			int c = s[i] - 'a';
    			if (!ch[p][c]) ch[p][c] = ++cnt, qwq[cnt] = c, fa[cnt] = p;
    			p = ch[p][c];
    		}
    	}
    
    	int pos[maxn];
    
    	void buildsam() {
    		queue<int> q;
    		for (int i = 0; i < 26; i++)
    			if (ch[1][i]) q.push(ch[1][i]);
    		pos[1] = 1;
    		while (!q.empty()) {
    			int u = q.front();
    			q.pop();
    			pos[u] = sam.ins(qwq[u], pos[fa[u]]);
    			for (int i = 0; i < 26; i++)
    				if (ch[u][i]) q.push(ch[u][i]);
    		}
    	}
    } trie;
    
    void cpy(int len) {
    	for(int i = 1 ; i <= len ; i ++) str[++ tot] = s[i] ;
    	str[++ tot] = '
    ' ;
    }
    
    int main() {
    	int _;
    	scanf("%d", &_);
    	for(int i = 1 ; i <= _ ; i ++) scanf("%s", s + 1), trie.ins(strlen(s + 1)), cpy(strlen(s + 1));
    	trie.buildsam(), sam.calc();
    	for(int i = 1 ; i <= _ ; i ++) printf("%lld
    " , Ans[i]) ;
    	return 0;
    }
    
  • 相关阅读:
    Java基础语法学习18——方法(2)
    Java基础语法学习17——方法(1)
    Java基础语法学习16——二维数组
    Java8新特性Lambda表达式
    Web编程规范之三层架构设计规范
    Mybatis初体验
    Servlet快速入门:第一个Servlet程序
    Java中常用IO流之文件流的基本使用姿势
    Java中异常关键字throw和throws使用方式的理解
    Java中关于泛型集合类存储的总结
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12568935.html
Copyright © 2011-2022 走看看