Atcoder 题面传送门 & 洛谷题面传送门

首先先考虑如果没有什么子集的限制怎样计算方案数。明显就是一个区间 \(dp\),这个恰好一年前就做过类似的题目了。我们设 \(f_{l,r}\) 为压缩 \([l,r]\) 的方案数,\(g_{l,r}\) 表示压缩 \([l,r]\),并且强制要求 \([l,r]\) 必须用括号括起来的方案数,那么 \(f_{l,r}\) 转移显然可以枚举第一段括号的位置,即 \(f_{l,r}=\sum\limits_{k=l-1}^rg_{l,k}f_{k+1,r}\)。\(g_{l,r}\) 转移就枚举循环节长度 \(len\),即 \(g_{l,r}=\sum f_{l,l+len-1}[len\ \text{为}\ s[l...r]\ \text{的循环节}]\)。

接下来考虑加上“子集”这个条件之后怎样计算答案,还是设 \(f_{l,r}\) 表示将 \([l,r]\) 所有子集压缩的方案数之和,\(g_{l,r}\) 表示将 \([l,r]\) 所有子集压缩,并且强制要求 \([l,r]\) 必须用括号括起来的方案数。显然 \(f\) 还是一样的转移方式,算 \(g\) 的时候就有些不同了,我们枚举 \(r-l+1\) 的所有约数 \(len\),并考虑 \(s[l...r]\) 中每一段长度为 \(len\) 的字符串,即 \(s[l...l+len-1],s[l+len...l+2len-1]\dots\),我们将这 \(\dfrac{r-l+1}{len}\) 个字符串每一位 AND 起来,然后求它的 \(f\) 值就行了,可以用记忆化搜索实现。

这个算法复杂度看起来不太对。但这只是看起来,事实上这样写即可通过此题。我们粗略估计一下可得 \(T(n)=\sum\limits_{i=1}^n(n-i+1)(\sum\limits_{d\mid i}(i+T(\dfrac{i}{d})))\),稍微打个表即可发现这个 \(T(n)\) 并不会特别大,因此这样写是没问题的。

这题告诉我们看到 \(n\le 100\) 不要习惯性地想 \(n^4\) 或 \(n^3\log n\),有的复杂度奇怪的解法也可以通过这种小数据。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MOD=998244353;
map<string,int> f,g;
string s;
int calcg(string s);
int calcf(string s){
if(s==""||s=="0") return 1;
if(s=="1") return 2;
if(f.count(s)) return f[s];
int ret=0;for(int i=1;i<=s.size();i++){
string s1,s2;
for(int j=0;j<i;j++) s1+=s[j];
for(int j=i;j<s.size();j++) s2+=s[j];
ret=(ret+1ll*calcg(s1)*calcf(s2))%MOD;
} return f[s]=ret;
}
int calcg(string s){
if(s==""||s=="0") return 1;
if(s=="1") return 2;
if(g.count(s)) return g[s];
int ret=0;
for(int i=1;i<s.size();i++){
if(s.size()%i) continue;string t="";
for(int j=0;j<i;j++){
int flg=1;
for(int k=j;k<s.size();k+=i) flg&=(s[k]-'0');
t+=(flg^48);
} ret=(ret+calcf(t))%MOD;
} return g[s]=ret;
}
int main(){
cin>>s;printf("%d\n",calcf(s));
return 0;
}

Atcoder Grand Contest 020 E - Encoding Subsets(记忆化搜索+复杂度分析)的更多相关文章

  1. AtCoder Grand Contest 020 (AGC020) E - Encoding Subsets 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/AGC020E.html 前言 真 \(\cdot\) 信仰型动态规划 题解 我们可以采用信仰型动态规划解决此题. 设 \(dp[ ...

  2. Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)

    Atcoder 题面传送门 & 洛谷题面传送门 一道难度 unavailable 的 AGC F 哦 首先此题最棘手的地方显然在于此题的坐标可以为任意实数,无法放入 DP 的状态,也无法直接计 ...

  3. AtCoder Grand Contest 020

    A - Move and Win Time limit : 1sec / Memory limit : 512MB Score : 300 points Problem Statement A gam ...

  4. AtCoder Grand Contest 020 D - Min Max Repetition

    q<=1000个询问,每次问a,b,c,d:f(a,b)表示含a个A,b个B的字符串中,连续A或连续B最小的串中,字典序最小的一个串,输出这个串的c到d位.a,b<=5e8,d-c+1&l ...

  5. AtCoder Grand Contest 020 题解

    传送门 怎么又是\(tourist\)神仙的题-- \(A\) 咕咕 int n,a,b; int main(){ scanf("%d%d%d",&n,&a,&am ...

  6. 专题1:记忆化搜索/DAG问题/基础动态规划

      A OpenJ_Bailian 1088 滑雪     B OpenJ_Bailian 1579 Function Run Fun     C HDU 1078 FatMouse and Chee ...

  7. AtCoder Grand Contest 012 B Splatter Painting (反向处理 + 记忆化)

    题目链接  agc012 Problem B 题意  给定一个$n$个点$m$条边的无向图,现在有$q$个操作.对距离$v$不超过$d$的所有点染色,颜色编号为$c$. 求每个点最后的颜色状态. 倒过 ...

  8. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  9. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

随机推荐

  1. 【c++ Prime 学习笔记】第5章 语句

    C++提供了一组控制流语句,包括条件执行语句.循环语句.跳转语句. 5.1 简单语句 空语句 ; ,最简单的语句 别漏写分号,也别多写 while(cin>>s && s! ...

  2. [Beta]the Agiles Scrum Meeting 3

    会议时间:2020.5.14 20:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 yjy 实现前端界面美化 tq 实现查看.删除测试点功能的前端修复功能中的bug wjx 升级系统实现 ...

  3. Codeforces Round #573 (Div. 2) D题题解

    一.题目 ​ Tokitsukaze, CSL and Stone Game ​ Tokitsukaze和CSL正在玩一些石头游戏. ​ 一开始,有n堆的石头,第i堆石头数记为 \(a_i\),两人轮 ...

  4. 震惊,hzoi的考试竟然折磨简单,活到爆!

    众所周知,hzoi的考试题非常"简单",那么究竟有多简单呢?最近,一位外国小哥开发出了hzoi的考试竟然折磨简单,活到爆!的方法,这究竟是怎么一回事呢?快和小编一起来看看吧- 满分 ...

  5. 六个好习惯让你的PCB设计更优

    PCB layout工程师每天对着板子成千上万条走线,各种各样的封装,重复着拉线的工作,也许很多人会觉得是很枯燥无聊的工作内容.看似软件操作搬运工,其实设计人员在过程中要在各种设计规则之间做取舍,兼顾 ...

  6. C# 如何将日期格式化ISO8601模式

    类似于这样的时间戳格式:预计来访时间,时间参数需满足ISO8601格式:yyyy-MM-ddTHH:mm:ss+当前时区,例如北京时间:2018-07-26T15:00:00 + 08:00 stri ...

  7. (转)linux下execl和system函数

    linux下,system函数和execl函数都是用于执行一条系统命令.今天仔细看了system函数的实现,想找出和execl函数的差别. 这里先进行一些背景知识补充: fork(创建一个新的进程): ...

  8. AtCoder Beginner Contest 182 F

    F - Valid payments 简化题意:有\(n\)种面值的货币,保证\(a[1]=1,且a[i+1]是a[i]的倍数\). 有一个价格为\(x\)元的商品,付款\(y\)元,找零\(y-x\ ...

  9. Typecho部署小破站

    写在前面 以前利用 Github Page + Hexo框架 + Next主题搭建过静态博客,没错就是那个黑白色系的网页!但是体验并不是很好,一来本身是静态网页,页面内容要修改都需要在本地修改完上传到 ...

  10. Linux下的 sniff-andthen-spoof程序编写

    Linux下的 sniff-andthen-spoof程序编写 一.任务描述 在本任务中,您将结合嗅探和欺骗技术来实现以下嗅探然后欺骗程序.你需要两台机器在同一个局域网.从机器A ping IP_X, ...