zoukankan      html  css  js  c++  java
  • [洛谷P4248][AHOI2013]差异

    题目大意:给一个长度为$n$的字符串,求:

    $$
    sumlimits_{1leqslant i<jleqslant n}|suf_i|+|suf_j|-2 imes lcp(suf_i,suf_j)
    $$

    题解:建一棵后缀树,这个式子就成了后缀树上所有后缀之间的距离(后缀树可以把字符串反着加入后缀自动机得到的$fail$数组而来),然后有两种做法:

    1. 把$sumlimits_{1leqslant i<jleqslant n}|suf_i|+|suf_j|$直接求出来
    $$
    egin{align*}
    &sumlimits_{1leqslant i<jleqslant n}|suf_i|+|suf_j|\
    =&sumlimits_{1leqslant i<jleqslant n}i+j\
    =&dfrac{n(n+1)(n-1)} 2
    end{align*}
    $$
    然后对每个点考虑它作为$lca$的贡献

    2. 直接考虑每条边的贡献

    卡点:

    C++ Code:(方法一)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 500010
    
    namespace SAM {
    #define N (maxn << 1)
    	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;
    	}
    
    	int R[N], fail[N], nxt[N][26];
    	int lst = 1, idx = 1;
    	int sz[N];
    	void append(char __ch) {
    		int ch = __ch - 'a';
    		int p = lst, np = lst = ++idx;
    		R[np] = R[p] + 1; sz[np] = 1;
    		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[q] == R[p] + 1) fail[np] = q;
    			else {
    				int nq = ++idx;
    				std::copy(nxt[q], nxt[q] + 26, nxt[nq]);
    				fail[nq] = fail[q], R[nq] = R[p] + 1, fail[np] = fail[q] = nq;
    				for (; p && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq;
    			}
    		}
    	}
    
    	long long ans;
    	void dfs(int u) {
    		long long tmp = 0;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			dfs(v);
    			tmp += static_cast<long long> (sz[u]) * sz[v];
    			sz[u] += sz[v];
    		}
    		ans += 2 * tmp * R[u];
    	}
    	long long work() {
    		for (int i = 2; i <= idx; i++) addedge(fail[i], i);
    		dfs(1);
    		return ans;
    	}
    #undef N
    }
    
    int n;
    char s[maxn];
    long long ans;
    int main() {
    	scanf("%s", s + 1);
    	n = strlen(s + 1);
    	for (int i = n; i; i--) SAM::append(s[i]);
    	ans = static_cast<long long> (n - 1) * n * (n + 1) / 2;
    	ans -= SAM::work();
    	printf("%lld
    ", ans);
    	return 0;
    }
    

      

    C++ Code:(方法二)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 500010
    
    long long ans;
    int n;
    namespace SAM {
    #define N (maxn << 1)
    	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;
    	}
    
    	int R[N], fail[N], nxt[N][26];
    	int lst = 1, idx = 1;
    	int sz[N];
    	void append(char __ch) {
    		int ch = __ch - 'a';
    		int p = lst, np = lst = ++idx;
    		R[np] = R[p] + 1; sz[np] = 1;
    		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[q] == R[p] + 1) fail[np] = q;
    			else {
    				int nq = ++idx;
    				std::copy(nxt[q], nxt[q] + 26, nxt[nq]);
    				fail[nq] = fail[q], R[nq] = R[p] + 1, fail[np] = fail[q] = nq;
    				for (; p && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq;
    			}
    		}
    	}
    
    	void dfs(int u) {
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			dfs(v);
    			sz[u] += sz[v];
    			ans += static_cast<long long> (n - sz[v]) * (sz[v]) * (R[v] - R[u]);
    		}
    	}
    	void work() {
    		for (int i = 2; i <= idx; i++) addedge(fail[i], i);
    		dfs(1);
    	}
    #undef N
    }
    
    char s[maxn];
    int main() {
    	scanf("%s", s + 1);
    	n = strlen(s + 1);
    	for (int i = n; i; i--) SAM::append(s[i]);
    	SAM::work();
    	printf("%lld
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    【JAVA】集合的使用:约瑟夫问题
    【JAVA】第八章:集合
    【数据结构】二叉树
    【数据结构】串
    【数据结构】KMP算法
    【java】快速入门:前八章内容总结
    【数据结构】停车场问题
    【实验向】问题:假设计算机A和计算机B通信,计算机A给计算机B发送一串16个字节的二进制字节串,以数组形式表示:
    【数据结构】括号的匹配问题
    CSS
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10161164.html
Copyright © 2011-2022 走看看