zoukankan      html  css  js  c++  java
  • [AHOI 2013]差异

    题意:求\(\sum_{1<=i<j<=n} len(T_i) + len(T_j) - 2*LCP(T_i,T_j)\)

    思路:首先考虑把式子化简一下:

    原式
    = \(\sum_{1<=i<j<=n} len(T_i) + len(T_j) - 2 * \sum_{1<=i<j<=n}LCP(T_i,T_j)\)

    = $\sum_{1<=i<j<=n} (n - i + 1) + (n - j + 1) - 2 * \sum_{1<=i<j<=n}LCP(T_i,T_j) $
    = \(((n + 1) * n * (n - 1) / 2) - 2 * \sum_{1<=i<j<=n}LCP(T_i,T_j)\)

    前面\(O(1)\)算一下,关键是后面求最长公共前缀,\(SAM\)跑一下即可,或者后缀树\(dp\)懒得写了)。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 500005;
    char s[maxn];
    int cnt = 1;
    int lst = 1;
    int rt = 1;
    int son[maxn << 1][26];
    int fa[maxn << 1];
    int dis[maxn << 1];
    int siz[maxn << 1];
    int _cnt;
    struct edge {
    	int to;
    	int nxt;
    }e[maxn << 2];
    ll ans;
    int head[maxn<<2];
    inline void extend(int c) {
    	int p = lst;
    	int np = ++cnt;
    	lst = np;
    	siz[np] = 1;
    	while(p && !son[p][c]) son[p][c] = np,p = fa[p];
    	if(!p) {
    		fa[np] = rt;
    	}
    	else {
    		int q = son[p][c];
    		if(dis[q] == dis[p] + 1) fa[np] = q;
    		else {
    			int nq = ++cnt;
    			memcpy(son[nq],son[q],sizeof(son[nq]));
    			fa[nq] = fa[q];
    			dis[nq] = dis[p] + 1;
    			fa[np] = fa[q] = nq;
    			while(son[p][c] == q) {
    				son[p][c] = nq;
    				p = fa[p];
    			}
    		}
    	}
    }
    inline void Add_edge(int u,int v) {
    	e[++_cnt].to = v;
    	e[_cnt].nxt = head[u];
    	head[u] = _cnt;return;
    }
    inline void dfs(int x) {
    	for(int i = head[x];i;i=e[i].nxt) {
    		int y = e[i].to;
    		dfs(y);
    		ans += (ll)siz[x] * siz[y] * dis[x];
    		siz[x] += siz[y];
    	}
    }
    int main () {
    	scanf("%s",s + 1);
    	int len = strlen(s + 1);
    	for(int i = len;i >= 1; --i) {
    		extend(s[i] - 'a');
    	}
    	for(int i = 2;i <= cnt; ++i) {
    		Add_edge(fa[i],i);
    	}
    	dfs(1);
    	printf("%lld\n",(ll)(len - 1) * len * (len + 1) / 2 - ans * 2);
    	return 0;
    }
    
  • 相关阅读:
    特性标签的灵活使用
    算法实例题
    网络抓包工具
    vs2010
    .NET Remoting vs Web Service
    电子商务网站设计学习
    EXCEL导出
    C# 16进制与字符串、字节数组之间的转换
    DES加密
    DataGridView生成CSV,XML 和 EXCEL文件
  • 原文地址:https://www.cnblogs.com/akoasm/p/9504278.html
Copyright © 2011-2022 走看看