AT4379 [AGC027E] ABBreviate

AT4379 [AGC027E] ABBreviate

分别记 aabb1122

则操作 si sjs_i \ s_j 即合并为 (si+sj)mod3(s_i+s_j) \bmod 3

值为 00 表示无法合并成一个;否则可以。

考虑通过若干次操作得到的一个字符串 tt

那么将全串从前往后贪心尽量取最短的段合并并与 tt 匹配,最后剩下的串一定模 3300 或是空串。

那么贪心从前往后匹配即可,具体见代码。

时间复杂度 O(n)\mathcal O(n)

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define ha putchar(' ')
#define he putchar('\n')

inline int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-')
			f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
		x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x * f;
}

inline void write(int x)
{
	if(x < 0)
	{
		putchar('-');
		x = -x;
	}
	if(x > 9)
		write(x / 10);
	putchar(x % 10 + 48);
}

const int mod = 1e9 + 7;

int n, f[100005], nxt[100005][3], s[100005], ans;

char c[100005];

signed main()
{
	scanf("%s", c + 1);
	n = strlen(c + 1);
	bool flg = 0;
	for(int i = 1; i < n; ++i)
		if(c[i] == c[i + 1]) {flg = 1; break;}
	if(!flg) {return puts("1"), 0;}
	for(int i = 1; i <= n; ++i) s[i] = (s[i - 1] + (c[i] == 'a' ? 1 : 2)) % 3;
	for(int i = 0; i < 3; ++i) nxt[n][i] = n + 1;
	for(int i = n; i >= 1; --i)
	{
		for(int j = 0; j < 3; ++j) nxt[i - 1][j] = nxt[i][j];
		nxt[i - 1][s[i]] = i;
	}
	f[0] = 1;
	for(int i = 0; i < n; ++i)
	{
		for(int j = 0; j < 3; ++j)
			if(s[i] != j) f[nxt[i][j]] = (f[nxt[i][j]] + f[i]) % mod;
		if(s[i + 1] == s[n]) ans = (ans + f[i + 1]) % mod;
	}
	write(ans), he;
	return 0;
}
posted @ 2022-07-18 19:30  蒟蒻orz  阅读(16)  评论(0)    收藏  举报  来源