zoukankan      html  css  js  c++  java
  • HDU 4416 (后缀自动机)

    HDU 4416 Good Article Good sentence

    Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现。
    Solution :首先对所有的T串建立后缀自动机,统计出本质不同的子串个数ans1,再将S串插入后缀自动机,统计出本质不同的子串个数ans2,则答案即为ans2-ans1。
    将多个串插入后缀自动机,只需要每次将last赋值为root即可。

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    const int N = 1000008;
    
    struct Suffix_Automaton
    {
    	int nt[N << 1][26], a[N << 1], fail[N << 1];
    	int tot, last, root;
    	int p, q, np, nq;
    	int newnode(int len)
    	{
    		for (int i = 0; i < 26; ++i) nt[tot][i] = -1;
    		fail[tot] = -1; a[tot] = len; 
    		return tot++;
    	}
    	void clear()
    	{
    		tot = last = 0; 
    		root = newnode(0);
    	}
    	void insert(int ch)
    	{
    		p = last; last = np = newnode(a[p] + 1); 
    		for (; ~p && nt[p][ch] == -1; p = fail[p]) nt[p][ch] = np;
    		if (p == -1) fail[np] = root;
    		else
    		{
    			q = nt[p][ch];
    			if (a[p] + 1 == a[q]) fail[np] = q;
    			else
    			{
    				nq = newnode(a[p] + 1);
    				for (int i = 0; i < 26; ++i) nt[nq][i] = nt[q][i];
    				fail[nq] = fail[q];
    				fail[np] = fail[q] = nq;
    				for (; ~p && nt[p][ch] == q; p = fail[p]) nt[p][ch] = nq;
    			}
    		}
    	}
    	long long solve()
    	{
    		long long ans = 0;
    		for (int i = 1; i < tot; ++i) ans += a[i] - a[fail[i]];
    		return ans;
    	}
    }sam;
    
    
    int main()
    {
    	cin.sync_with_stdio(0);
    	int T; cin >> T;
    	for (int cas = 1; cas <= T; ++cas)
    	{
    		sam.clear();
    		int n; cin >> n;
    		string s; cin >> s;
    		for (int i = 1; i <= n; ++i)
    		{
    			string t; cin >> t;
    			sam.last = 0;
    			for (int j = 0, len = t.length(); j < len; ++j)
    				sam.insert(t[j] - 'a');
    		}
    		long long ans1 = sam.solve();
    		sam.last = 0;
    		for (int j = 0, len = s.length(); j < len; ++j)
    			sam.insert(s[j] - 'a');
    		long long ans2 = sam.solve();
    		cout << "Case " << cas << ": " << ans2 - ans1 << endl;
    		
    	}	
    }
    
    
  • 相关阅读:
    iis 部署网站常见问题
    提高你开发效率的十五个Visual Studio 2010使用技巧
    SQL SERVER 错误代码 0x534
    SQL Server2005修改计算机名后不能发布订阅
    Fedora桌面系统Idea中的部分中文无法显示解决
    最近去滴滴面试的一道题:斐波拉契数列非递归实现
    二叉查找树之红黑树
    二叉查找树之AVL树
    二叉查找树
    再看SpringMVC通过一个DispatcherServlet处理Servlet
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/7218916.html
Copyright © 2011-2022 走看看