zoukankan      html  css  js  c++  java
  • APIO2014 回文串 回文自动机

    APIO2014 回文串 回文自动机

    题意

    定义(s)的一个子串的存在值为这个子串出现的次数乘子串的长度

    (s)的所有回文串的存在值

    [1 leq |s| leq 300000 ]

    分析

    (s)构建出回文自动机,(cnt)表示当前结点当前的出现次数,那么类似AC自动机的fail树,倒序对fail树的结点求siz即可得到结点的总出现次数

    然后乘上len即可

    代码

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define eps 1e-9
    #define db long double
    #define equals(a,b) fabs(a-b) < eps
    using namespace std;
    
    typedef long long ll;
    
    
    
    inline ll rd(){
    	ll x;
    	scanf("%lld",&x);
    	return x;
    }
    
    const int maxn = 3e5 + 5;
    char ss[maxn];
    
    namespace pam {
    	int sz, tot, last;
    	int cnt[maxn], ch[maxn][26], len[maxn], fail[maxn];
    	char s[maxn];
    	int node(int l) {
      		sz++;
      		memset(ch[sz], 0, sizeof(ch[sz]));
      		len[sz] = l;
      		fail[sz] = cnt[sz] = 0;
      		return sz;
    	}
    	void clear() {
      		sz = -1;
      		last = 0;
      		s[tot = 0] = '$';
      		node(0);
      		node(-1);
      		fail[0] = 1;
    	}
    	int getfail(int x) {
      		while (s[tot - len[x] - 1] != s[tot]) x = fail[x];
      		return x;
    	}
    	void insert(char c) {
      		s[++tot] = c;
      		int now = getfail(last);
      		if (!ch[now][c - 'a']) {
        		int x = node(len[now] + 2);
        		fail[x] = ch[getfail(fail[now])][c - 'a'];
      	 	 	ch[now][c - 'a'] = x;
      		}
      		last = ch[now][c - 'a'];
      		cnt[last]++;
    	}
    }
    
    int main(){
    	scanf("%s",ss + 1);
    	int len = strlen(ss + 1);
    	pam::clear();
    	for(int i = 1;i <= len;i++)
    		pam::insert(ss[i]);
    	ll ans = 0;
    	for(int i = pam::sz;i >= 1;i--)
    		pam::cnt[pam::fail[i]] += pam::cnt[i];
    	for(int i = 1;i <= pam::sz;i++)
    		ans = max(ans,(ll)(pam::cnt[i]) * (pam::len[i]));
    	cout << ans;
    }
    
  • 相关阅读:
    逻辑运算(二)
    Rust基础类型
    Rust简单demo
    逻辑基础(一)
    webpack配置typescript项目
    Go并发原理
    JS实现取任意类型的数组交集并集方法的思考
    JS 可逆加密的一种实现
    所有中文复姓
    将中文姓名转为拼音英文名的一种实现
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15007482.html
Copyright © 2011-2022 走看看