• 【UOJ #103】【APIO 2014】Palindromes


    http://uoj.ac/problem/103
    由manacher得:本质不同的回文串只有(O(n))个。
    用manacher求出所有本质不同的回文串,对每个本质不同的回文串,在后缀自动机的parent树上倍增求一下它出现了多少次,更新答案。
    时间复杂度(O(nlog n))

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 300003;
    
    char s[N], r[N << 1];
    int n, tot = 0, top = -1, endtot = 0;
    
    struct State {
    	State *par, *go[26], *fa[21];
    	int val, sum;
    } *root, *last, pool[N << 2], *endpos[N];
    
    State *newState(int num) {
    	State *t = &pool[++top];
    	t->val = num;
    	t->par = 0; t->sum = 0;
    	memset(t->go, 0, sizeof(t->go));
    	return t;
    }
    
    void extend(int w) {
    	State *p = last;
    	State *np = newState(p->val + 1);
    	while (p && p->go[w] == 0)
    		p->go[w] = np, p = p->par;
    	if (p == 0) np->par = root;
    	else {
    		State *q = p->go[w];
    		if (q->val == p->val + 1) np->par = q;
    		else {
    			State *nq = newState(p->val + 1);
    			memcpy(nq->go, q->go, sizeof(q->go));
    			nq->par = q->par; q->par = np->par = nq;
    			while (p && p->go[w] == q)
    				p->go[w] = nq, p = p->par;
    		}
    	}
    	endpos[++endtot] = last = np;
    	last->sum = 1;
    }
    
    int len[N << 1], id[N << 2];
    
    ll cal(int t, int l) {
    	State *p = endpos[t];
    	for (int i = 20; i >= 0; --i)
    		if (p->fa[i]->val >= l)
    			p = p->fa[i];
    	return 1ll * p->sum * l;
    }
    
    bool cmp(int x, int y) {return pool[x].val < pool[y].val;}
    
    int main() {
    	scanf("%s", s + 1);
    	n = strlen(s + 1);
    	root = last = newState(0);
    	for (int i = 1; i <= n; ++i)
    		extend(s[i] - 'a');
    	
    	r[0] = '#';
    	for (int i = 1; i <= n; ++i) {
    		r[++tot] = '$';
    		r[++tot] = s[i];
    	}
    	r[++tot] = '$';
    	r[++tot] = '&';
    	
    	root->par = &pool[top + 1]; root->par->fa[0] = root->par; root->par->val = -1;
    	for (int i = 0; i <= top; ++i) pool[i].fa[0] = pool[i].par;
    	for (int j = 1; j <= 20; ++j)
    		for (int i = 0; i <= top + 1; ++i)
    			pool[i].fa[j] = pool[i].fa[j - 1]->fa[j - 1];
    	
    	for (int i = 0; i <= top; ++i) id[i] = i;
    	stable_sort(id, id + top + 1, cmp);
    	for (int i = top; i >= 0; --i)
    		pool[id[i]].par->sum += pool[id[i]].sum;
    	
    	ll ans = 0;
    	int cur = 0, pos; len[0] = 1;
    	for (int i = 1; i < tot; ++i) {
    		int &now = len[i]; pos = (cur << 1) - i; now = 0;
    		now = min(len[pos], cur + len[cur] - i); now = max(now, 0);
    		while (r[i - now] == r[i + now]) {
    			++now;
    			if ((i + now - 1) & 1) continue;
    			ans = max(ans, cal((i + now - 1) >> 1, now));
    		}
    		if (i + now > cur + len[cur]) cur = i;
    	}
    	
    	printf("%lld
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    622 CircularQueue C#
    x盒子
    Cygwin、MinG、MSys区别与联系(转)
    Spring集成MyBatis完整示例
    mybatis学习 (五) POJO的映射文件
    mybatis学习(四)——config全局配置文件解析
    json字段为null时输出空字符串
    mybatis学习(一)不使用 XML 构建 SqlSessionFactory
    数据库 ----jdbc连接池的弊端
    Spring @Import注解 —— 导入资源
  • 原文地址:https://www.cnblogs.com/abclzr/p/6721456.html
Copyright © 2020-2023  润新知