码迷,mamicode.com
首页 > 其他好文 > 详细

2020.2.26考试T2 三元组

时间:2020-04-03 22:09:57      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:如何   ret   stream   个数   name   string   自动   display   void   

技术图片

首先我们正着对每一个 \(j\) 求一边 \(\displaystyle \sum i\),设为 \(a[j]\)

类似的倒着对每个 \(j\) 求一边 \(\displaystyle \sum k\),设为 \(b[j]\)

那么答案就是 \(\displaystyle \sum a[i] \times b[i+1]\)

考虑如何求 \(a\) 我们在建立回文自动机的时候统计一下以 \(j\) 为结尾的回文串的个数 \(num\) 以及回文串的长度和 \(sum\), 则 \(a[j]=(i+1) \times num -sum\)

倒着也同理

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
using namespace std;
int T, n;
LL ans;
const int N = 1000010, mod = 1e9 + 7;
int a[N], b[N];
char s[N];
struct PAM
{
	int em, last, cnt, now;
	int tr[N][26], len[N], fail[N], sum[N], num[N];
	void YYCH()
	{
		for (int i = 0; i <= cnt; ++i)
		{
			len[i] = num[i] = fail[i] = sum[i] = 0;
			for (int j = 0; j < 26; ++j)tr[i][j] = 0;
		}
		fail[0] = 1; fail[1] = 0; len[0] = 0; len[1] = -1; cnt = 1; last = 0;
	}
	int getfail(int x)
	{
		if (now == 1)while (s[em - len[x] - 1] != s[em])x = fail[x];
		else while (s[em + len[x] + 1] != s[em])x = fail[x];
		return x;
	}
	void Insert(int x)
	{
		int f1 = getfail(last);
		if (!tr[f1][x])
		{
			len[++cnt] = len[f1] + 2;
			fail[cnt] = tr[getfail(fail[f1])][x];
			num[cnt] = num[fail[cnt]] + 1;
			sum[cnt] = sum[fail[cnt]] + len[cnt]; sum[cnt] %= mod;
			tr[f1][x] = cnt;
		}
		last = tr[f1][x];
	}
} P;
int main()
{
	freopen("triple.in", "r", stdin);
	freopen("triple.out", "w", stdout);
	cin >> T;
	while (T--)
	{
		scanf("%s", s + 1); n = strlen(s + 1); ans = 0;
		P.YYCH(); P.now = 1;
		for (int i = 1; i <= n; ++i)
		{
			P.em = i; P.Insert(s[i] - ‘a‘);
			a[i] = ((LL)(i + 1) * P.num[P.last] - P.sum[P.last]) % mod;
		}
		P.YYCH(); P.now = 2;
		for (int i = n; i >= 1; --i)
		{
			P.em = i; P.Insert(s[i] - ‘a‘);
			b[i] = ((LL)(i - 1) * P.num[P.last] + P.sum[P.last]) % mod;
		}
		for (int i = 1; i < n; ++i)(ans += (LL)a[i] * b[i + 1]) %= mod;
		cout << (ans % mod + mod) % mod << ‘\n‘;
	}
	fclose(stdin); fclose(stdout);
	return 0;
}

2020.2.26考试T2 三元组

标签:如何   ret   stream   个数   name   string   自动   display   void   

原文地址:https://www.cnblogs.com/wljss/p/12628908.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!