Description

AGC027E

给定一个仅由\(AB\)构成的字符串\(S\),给定两个操作,把\(AA\)换成\(B\),和把\(BB\)换成\(A\),问由这个字符串和任意次操作可以得到几种字符串。

Solution

AGC好难啊(摔

首先,如果不能操作,答案是\(0\)。

我们令\(A=1,B=2\),这样就会有一个美妙的性质:所有字符的和在操作的时候在模\(3\)意义下不变,我们记这个和为\(p(S)\)。然后我们可以得到一个结论:一个字符串\(S\)可以变成字符\(c\),当且仅当:\(S=c\)或\(p(S)=p(c)\)且\(S\)可以操作。这个条件的必要性很好证明,而充分性证明也比较简单:当\(S\)中的连续字符长度为\(2\)时,可以合并这两个字符,并且字符串长度减小;而当\(S\)中的连续字符长度大于\(2\)时,可以合并与不同字符相邻的那一端的字符(如果只有一种字符的话,自己证吧),字符串长度也减少;这样,字符串长度不断减少,一定可以达到\(1\),这时的\(S'=c\)。

这样问题就转化为:求出这样的\(T\)的数量:将\(S\)划分为\(|T|\)段,第\(i\)段的\(p\)值与\(T\)中的第\(i\)个字符的\(p\)值相等。我们可以贪心的构造这样的\(T\):让每一段的长度尽可能的小,如果分出\(|T|\)段后,剩余部分的\(p\)值为\(0\),那就是一个合法的\(T\)。

这样,就只需要一个简单的DP就行了我们递推的来做,\(f_i\)表示前\(i\)个字符看作一段的方案数,如果\(p(S_{i+1,n})=0\),那么\(i\)之后的位置可以看成是剩余的位置,\(f_i\)的初值为\(1\),否则为\(0\)。然后,我们可以在\(i\)之后加一段\(A\)或是\(B\),这样就要记录各个\(p\)值最后一次出现的位置,累加即可。具体实现看代码。

Code

#include <cstdio>

const int N = 1e5 + 10;
const int MOD = 1e9 + 7; char s[N];
int a[N], n, f[N], nxt[3]; int main() {
scanf("%s", s);
for (; s[n]; ++n) a[n+1] = (a[n] + s[n] - 'a' + 1) % 3; // 求前缀和
// 判断是否可以操作
int flag = 0;
for (int i = 1; i < n; ++i) {
if (s[i] == s[i-1]) flag = 1;
}
if (!flag) {
puts("1");
return 0;
}
// 递推
f[n] = 1;
for (int i = 0; i < 3; ++i) nxt[i] = i == a[n] ? n : n + 1;
for (int i = n-1; i; --i) {
f[i] = a[i] == a[n]; // 后面可不可以不分段
for (int c = 1; c <= 2; ++c) {
(f[i] += f[nxt[(a[i]+c)%3]]) %= MOD; // 后面加一段A或B
}
nxt[a[i]] = i; // 记录该p值最后一次出现的位置
}
printf("%d\n", (f[nxt[1]] + f[nxt[2]]) % MOD);
return 0;
}

[AGC027E]ABBreviate的更多相关文章

  1. AGC027 E - ABBreviate

    目录 题目链接 题解 代码 题目链接 AGC027 E - ABBreviate 题解 神仙啊 建议查看https://img.atcoder.jp/agc027/editorial.pdf 定义a ...

  2. java stopwatch 功能

    C#中有一个stopwatch的功能,主要是用来监测程序执行时间的.java之前一直都在用如下方式完成: public static void main(String[] args) { long s ...

  3. gradle学习笔记

    一直想着花时间学习下gradle,今天有空.入门一下.参考:极客学院gradle使用指南,官方文档:gradle-2.12/docs/userguide/installation.html,以及百度阅 ...

  4. Linux监控工具介绍系列——smem

    smem工具介绍 smem是Linux系统上的一款可以生成多种内存耗用报告的命令行工具.与现有工具不一样的是smem可以报告实际使用的物理内存(PSS),这是一种更有意义的指标.可以衡量虚拟内存系统的 ...

  5. StringUtils工具类

    StringUtils源码,使用的是commons-lang3-3.1包.下载地址 http://commons.apache.org/lang/download_lang.cgi 以下是String ...

  6. POJ2001Shortest Prefixes[Trie]

    Shortest Prefixes Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 17683   Accepted: 768 ...

  7. StringUtils中的常用的方法

    org.apache.commons.lang.StringUtils中常用的方法,这里主要列举String中没有,且比较有用的方法: 1. 检查字符串是否为空: static boolean isB ...

  8. Google C++ Style Guide

    Background C++ is one of the main development languages used by many of Google's open-source project ...

  9. Apache Commons Lang

    http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/package- ...

随机推荐

  1. [POI2008] PLA-Postering - 单调栈

    给你 \(n\) 个相连的矩形建筑,让你用最少海报把他们覆盖掉,海报不能重叠,也不可以高出被覆盖的矩形. Solution 考虑维护一个单调递增的栈,每次插入时弹掉所有比自己高的,如果自己和末端一样高 ...

  2. PHPstorm主题、插件等相关推荐

    自己想升级PHPstorm,但是一直升级不了,捣腾一下午,终于它over掉了. 重新下载安装,发现应该把自己喜欢的插件.主题配色等记录一下. material theme UI主题插件 不知道为啥,看 ...

  3. spark之RDD练习

    目录 一.基础练习 练习一:翻倍列表中的数值并排序列表,并选出其中大于等于10的元素. 练习二:将字符数组里面的每一个元素先切分在压平. 练习三:求两个列表中的交集.并集.及去重后的结果 练习四:对L ...

  4. [转]从实例谈OOP、工厂模式和重构

    有了翅膀才能飞,欠缺灵活的代码就象冻坏了翅膀的鸟儿.不能飞翔,就少了几许灵动的气韵.我们需要给代码带去温暖的阳光,让僵冷的翅膀重新飞起来.结合实例,通过应用OOP.设计模式和重构,你会看到代码是怎样一 ...

  5. jQuery---基本的选择器

    基本选择器 名称 用法 描述 ID选择器 $(“#id”); 获取指定ID的元素 类选择器 $(“.class”); 获取同一类class的元素 标签选择器 $(“div”); 获取同一类标签的所有元 ...

  6. pytest-pytest-html生成HTML测试报告

    pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告.兼容Python 2.7,3.6 pytest-html 1.github上源码地址[https://github.com ...

  7. CodeForces 1144C

    链接 https://vjudge.net/problem/CodeForces-1144C #include<bits/stdc++.h> using namespace std; in ...

  8. vjudge 棋盘

    原题目链接:https://vjudge.net/contest/331118#problem/B 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放 ...

  9. rp算法 随机化 刷题记录

    刷随机化是真的会上瘾quq 洛谷P3973 [TJOI2015]线性代数 看oiwiki上说可以随机化...于是... 就随机在a[i]上选一位取反,然后更新答案,最后输出答案. ...无话可说 代码 ...

  10. 利用 Hexo + Github 搭建自己的博客

    扯在前面 在很久很久以前,一直就想搭建属于自己的一个博客,但由于各种原因,最终都不了了之,恰好最近突然有了兴趣,于是就自己参照网上的教程,搭建了属于自己的博客. 至于为什么要搭建自己的博客了?哈哈,大 ...