Atcoder Grand Contest 020 E - Encoding Subsets(记忆化搜索+复杂度分析)
首先先考虑如果没有什么子集的限制怎样计算方案数。明显就是一个区间 \(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(记忆化搜索+复杂度分析)的更多相关文章
- AtCoder Grand Contest 020 (AGC020) E - Encoding Subsets 动态规划
原文链接www.cnblogs.com/zhouzhendong/p/AGC020E.html 前言 真 \(\cdot\) 信仰型动态规划 题解 我们可以采用信仰型动态规划解决此题. 设 \(dp[ ...
- Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)
Atcoder 题面传送门 & 洛谷题面传送门 一道难度 unavailable 的 AGC F 哦 首先此题最棘手的地方显然在于此题的坐标可以为任意实数,无法放入 DP 的状态,也无法直接计 ...
- AtCoder Grand Contest 020
A - Move and Win Time limit : 1sec / Memory limit : 512MB Score : 300 points Problem Statement A gam ...
- 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 ...
- AtCoder Grand Contest 020 题解
传送门 怎么又是\(tourist\)神仙的题-- \(A\) 咕咕 int n,a,b; int main(){ scanf("%d%d%d",&n,&a,&am ...
- 专题1:记忆化搜索/DAG问题/基础动态规划
A OpenJ_Bailian 1088 滑雪 B OpenJ_Bailian 1579 Function Run Fun C HDU 1078 FatMouse and Chee ...
- AtCoder Grand Contest 012 B Splatter Painting (反向处理 + 记忆化)
题目链接 agc012 Problem B 题意 给定一个$n$个点$m$条边的无向图,现在有$q$个操作.对距离$v$不超过$d$的所有点染色,颜色编号为$c$. 求每个点最后的颜色状态. 倒过 ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
随机推荐
- .NET 分布式系统架构(有转载部分)
一.设计目的 搭建一个大型平台需要综合考虑很多方面,不单纯是软件架构,还包括网络和硬件设备等.由于现代大部分应用建设都面临用户多.高并发.高可用的需求,传统软件架构已不能满足需求,需要支持分布式软件架 ...
- 【数据结构与算法Python版学习笔记】树——树的遍历 Tree Traversals
遍历方式 前序遍历 在前序遍历中,先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树. 中序遍历 在中序遍历中,先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树. 后序遍 ...
- 如何获取ISO8601定义的Work Week
工作中遇到一个需求,需要在打印标签的时候打印生产当天的工作周.工作周按照ISO-8601定义的标准计算.找到两种方案. Excel函数 C#代码 Excel函数 非常简单,调用一个Excel自带函数就 ...
- [技术博客] BeautifulSoup4分析网页
[技术博客] BeautifulSoup4分析网页 使用BeautifulSoup4进行网页文本分析 前言 进行网络爬虫时我们需要从网页源代码中提取自己所需要的信息,分析整理后存入数据库中. 在pyt ...
- Sharding-JDBC自定义复合分片算法
Sharding-JDBC自定义复合分片算法 一.背景 二.需求 1.对于客户端操作而言 2.对于运营端操作而言 三.分片算法 1.客户id和订单id的生成规则 2. 确定数据落在那个表中 3.举例说 ...
- 【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)
简介 学习Redis Cluster的第一步,即本地搭建Redis Cluster.但是在Redis的官方文档中,是介绍在Linux系统中搭建Redis Cluster.本文主要介绍在Windows系 ...
- jzoj6094
题目描述 给定一个循环流(每个点均满足流量平衡条件),这个循环流有$n$个点,且每条边的流量只有 $1$ 或$ 2$,其中$a$条边流量为$1$,$b$条边流量为$2$,判断是否存在一个流满足上述条件 ...
- Celery Task(定时任务)及参数
celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...
- AXI总线简介、ID分析、DMA、Vivado烧录、系统集成
转载:https://blog.csdn.net/CrazyUncle/article/details/89918030?depth_1-utm_source=distribute.pc_releva ...
- (转)linux下execl和system函数
linux下,system函数和execl函数都是用于执行一条系统命令.今天仔细看了system函数的实现,想找出和execl函数的差别. 这里先进行一些背景知识补充: fork(创建一个新的进程): ...