AT4379 [AGC027E] ABBreviate
AT4379 [AGC027E] ABBreviate
分别记 、 为 、。
则操作 即合并为 。
值为 表示无法合并成一个;否则可以。
考虑通过若干次操作得到的一个字符串 。
那么将全串从前往后贪心尽量取最短的段合并并与 匹配,最后剩下的串一定模 余 或是空串。
那么贪心从前往后匹配即可,具体见代码。
时间复杂度 。
#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;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121995