正睿OI 提高 Day1T3 ZYB玩字符串(DP)
设可能的答案串为p,长为len。p一定是s的一个子串且len|n。
虽然一些p在s中可能被断成若干段,但删掉其中的若干段后,这段区间一定会被全部消掉。
于是枚举p后,可以用f[i][j]表示区间[i,j]是否合法。len不需要整除区间长度,多余的部分要匹配p的前缀(匹配什么后缀啊,大不了从前面开始)。
f[i][j]可以由j-1拼,即 \(f[i][j]|=f[i][j-1]\ \&\&\ s[j]==p[(l-1)/l+1] (l=j-i+1)\)。
也可以是j和前面构成了可消除的串,之后可以跳过这些串继续匹配,即 \(f[i][j]|=f[i][j-k*len]\ \&\&\ f[j-k*len+1][j]\)。
第二种转移的上界是\(O(\frac{n}{len})\)的。
复杂度约是\(O(\sum_{len|n}(n-len+1)*n^2*n/len)=O(n^4)\)。对p判一下重,再判字符集合法性,跑的就很快了。
//285ms 17216kb(string怎么那么快。。)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define mod (20000000)
const int N=205;
int n,q[N*N],cnt[233],cnt2[233];
bool vis[20000001],f[N][N];
char s[N],p[N],ans[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline int Hash(int l)
{
int x=0;
for(int i=1; i<=l; ++i) x=(x*37+p[i]-'A')%mod;
return x;
}
void Update()
{
if(ans[1]=='{') for(int i=1; i<=n; ++i) ans[i]=p[i];
else
{
for(int i=1; i<=n; ++i) if(p[i]>ans[i]) return;
for(int i=1; i<=n; ++i) ans[i]=p[i];
}
}
bool Solve(int len)
{
for(int i=1; i<=n; ++i) f[i][i]=s[i]==p[1];
for(int l=2; l<=n; ++l)
{
for(int i=1,j; (j=i+l-1)<=n; ++i)
{
f[i][j]=0;
if(f[i][j-1]&&s[j]==p[(l-1)%len+1]) f[i][j]=1;
else
for(int k=1; j>=i+k*len; ++k)
if(f[i][j-k*len]&&f[j-k*len+1][j]) {f[i][j]=1; break;}
}
}
return f[1][n];
}
int main()
{
for(int T=read(); T--; )
{
ans[1]='{'; int t=0;
scanf("%s",s+1), n=strlen(s+1);// cin>>s; s=""+s;
for(int i=1; i<=n; ++i) ++cnt[s[i]];
for(int len=1; len<=n; ++len)
if(!(n%len))
{
for(int l=0,val; l+len<=n; ++l)
{
for(int i=1; i<=len; ++i) p[i]=s[l+i];// p=s.substr(l+1,l+len)
for(int i=1; i<=len; ++i) ++cnt2[p[i]];
bool f=1;
for(int i='a'; i<='z'; ++i) if(cnt2[i]&&cnt[i]%cnt2[i]) {f=0; break;}//cnt2!=0。。
for(int i=1; i<=len; ++i) --cnt2[p[i]];
if(!f) continue;
if(!vis[val=Hash(len)]) vis[val]=1, q[++t]=val;
else continue;
if(Solve(len)) Update();
}
if(ans[1]!='{') {ans[len+1]='\0', puts(ans+1); break;}
}
for(int i=1; i<=t; ++i) vis[q[i]]=0;
for(int i=1; i<=n; ++i) --cnt[s[i]];
}
return 0;
}
正睿OI 提高 Day1T3 ZYB玩字符串(DP)的更多相关文章
- 正睿OI提高组十连测 day1 总结
可能是最简单的一场比赛了吧,结果却打得这么差... T1是个找规律题,结果一开始愚蠢地找错了规律,然后又对拍,到1h多一点才过掉 然后看t2和t3,以为t2是个水题,t3也只要处理一下就好了,先写t2 ...
- 正睿OI DAY3 杂题选讲
正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...
- 正睿OI国庆DAY2:图论专题
正睿OI国庆DAY2:图论专题 dfs/例题 判断无向图之间是否存在至少三条点不相交的简单路径 一个想法是最大流(后来说可以做,但是是多项式时间做法 旁边GavinZheng神仙在谈最小生成树 陈主力 ...
- 正睿OI国庆day1
正睿OI国庆day1 T1 \[ S_n=1*S_{n-1}+1*F_{n-1}+1*F_{n-2}+1*f_{n-1}+1*f_{n-2} \] \[ F_{n}=0*S_{n-1}+1*F_{n- ...
- 正睿OI集训游记
什么嘛....就是去被虐的... 反正就是难受就是了.各种神仙知识点,神仙题目,各式各样的仙人掌..... 但是还是学会了不少东西...... 应该是OI生涯最后一次集训了吧.... 这次的感言还是好 ...
- 『正睿OI 2019SC Day8-Day17』
于是就迎来\(10\)天的自闭考试了,每天写点小总结吧. Day8 第一天就很自闭啊,考题分别是数学题+建模题+图论. 前两道题都没有什么算法,但是难度还是有的,于是就做不太出来,特别是第一题.第二题 ...
- [JZOJ6347]:ZYB玩字符串(DP+记忆化搜索)
题目描述 $ZYB$获得了一个神秘的非空字符串$p$. 初始时,串$S$是空的. $ZYB$会执行若干次这样的操作: $1.$选取$S$中的一个任意的位置(可以是最前面或者最后面) $2.$在这个位置 ...
- [JZOJ6347] 【NOIP2019模拟2019.9.8】ZYB玩字符串
题目 题目大意 有一个字符串\(p\).一开始字符串\(s\)为空串. 接下来进行若干次操作:在\(s\)的某个空隙中插入\(p\). 给出操作后的\(s\),问长度最小的\(p\). 思考历程 感觉 ...
- 【正睿oi省选十连测】第一场
四小时写了两个暴力??自闭 [原来这就是神仙们的分量Orz rank 56/75 可以说是无比垃圾了 下周目标:进步十名?[大雾 T1 题意:有n个点的图 点有点权Ai 也有点权Bi = A_1 + ...
随机推荐
- Scala进阶之路-Scala特征类与unapply反向抽取
Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...
- 从url到页面加载浏览器做了什么?
从输入url到页面加载发生了什么?1.DNS解析DNS解析是一个递归查询的过程.DNS解析的过程就是寻找哪台机器上有你需要资源的过程,当你在浏览器中输入一个地址时,www.baidu.com.其实不是 ...
- Redis 学习小记
由于是学习笔记,我就不来各种啰嗦,介绍这个介绍那个,也不上交给国家,或者各种对比,相信如果你真心用 redis 的话,就不会去跟 MySql,Memcached,MongoDB 等做对比了. 我原先用 ...
- Windows bat 学习(高级)
有一种叫做 Command Processor Extensions 的东西,即命令处理器扩展.他会使命令更加高级,功能更多. 在 cmd 里可以使用 ECHO %CMDEXTVERSION% 查看当 ...
- java concurrent 中ExecutorService和CompletionService简单区别
举个例子,现在需要执行10个任务,这些任务都是有返回值,并且需要使用10个线程同时执行.一般的做法就是创建ExecutorService线程池,pool大小10,每个任务实现Callable接口,然后 ...
- 玩转Hook——Android权限管理功能探讨(一)
随着Android设备上的隐私安全问题越来越被公众重视,恶意软件对用户隐私,尤其是对电话.短信等私密信息的威胁日益突出,各大主流安全软件均推出了自己的隐私行为监控功能,在root情况下能有效防止恶意软 ...
- HDU 3787 A+B 模拟题
解题报告:就是输入两个用逗号隔开的数字,求出这两个数字的和,并且用正常的方式输出来.直接写一个函数将一个包含逗号的数字转换成十进制的数返回就行了.这里推荐一个函数atoi(),参数是char*型的,然 ...
- 在vue-cli下读取模拟数据请求服务器
写此记录时vue脚手架的webpack是3.6.0 此文章方法亦可用于vue-cli3,直接在vue.config.js里面添加 本记录使用vue-resource,先安装: cnpm install ...
- Django进阶之缓存和信号
一.缓存 简介 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者mem ...
- Python 入门基础5 --元组、字典、集合
今日目录: 一.元组 二.字典 三.集合 四.后期添加内容 一.元组 1.定义 t1 = () # 参数为for可以循环的对象(可迭代对象) 思考: 如何定义一个只有一个值的元组? ("li ...