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;
    }
    
  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15007482.html
Copyright © 2011-2022 走看看