题目传送门


分析

显然如果存在长度大于一半的border那么必然存在小于一半的 border,所以容斥一下,

设 \(dp[i]\) 表示长度为 \(i\) 的不存在公共前后缀的字符串个数,那么 \(dp[i]=2^i-\sum_{j=1}^{\lfloor\frac{i}{2}\rfloor}dp[j]\times 2^{i-2j}\)

问题就是怎么求字典序第 \(k\) 个字符串,考虑试填字母a之后统计方案数是否足够,不够就填b,

有一些区别就是前缀是固定的所以2的幂次会相应减少,并且枚举的 \(j\) 需要判断是否存在这样的 border

这就需要KMP去判断当前填的 \(i\) 个字母有哪些 border


代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N=71;
typedef unsigned long long ull;
int n,Q,flag,fail[N],v[N],s[N];
ull k,two[N],dp[N],f[N];
ull calc(int i){
int j=i;
while (j) v[j]=1,j=fail[j];
for (int j=i+1;j<=n;++j){
f[j]=two[j-i];
for (int k=1;k*2<=j;++k)
if (k<=j-i||v[k-(j-i)])
f[j]-=f[k]*two[max(0,j-k-max(i,k))];
}
for (int i=1;i<=n;++i) v[i]=0;
return f[n];
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
dp[0]=two[0]=1;
for (int i=1;i<=64;++i){
dp[i]=two[i]=two[i-1]<<1;
for (int j=1;j*2<=i;++j) dp[i]-=dp[j]*two[i-2*j];
}
for (cin>>Q;Q;--Q){
cin>>n>>k,cout<<dp[n]<<'\n';
if (n==1){
cout<<(k==1)?'a':'b'<<'\n';
continue;
}
if (k>dp[n]/2) flag=1,k=dp[n]-k+1;
else flag=0;
s[1]=0,f[1]=s[n]=1;
for (int i=2,j=0,J;i<n;++i){
s[i]=0,J=j;
while (j&&s[j+1]!=s[i]) j=fail[j];
if (s[j+1]==s[i]) ++j;
fail[i]=j,f[i]=!j;
ull t=calc(i);
if (t<k){
k-=t,s[i]=1,j=J;
while (j&&s[j+1]!=s[i]) j=fail[j];
if (s[j+1]==s[i]) ++j;
fail[i]=j,f[i]=!j;
}
}
for (int i=1;i<=n;++i) cout<<(char)(97+(s[i]^flag));
cout<<'\n';
}
return 0;
}

#KMP,容斥,dp#洛谷 5770 [JSOI2016] 无界单词的更多相关文章

  1. [JSOI2016]无界单词

    题目 题意:求\(\rm border\)长度为\(0\)的\(n\)位\(0,1\)字符串个数,并求字典序第\(k\)小的那一个. 首先是计数,正向不是很好算,考虑正难则反:设\(f_i\)表示长度 ...

  2. [JSOI2016]无界单词[动态规划、kmp]

    题意 题目链接 分析 对于第一问,枚举最终串最小的相同前后缀来统计答案. 由于最小的相同前后缀也是无界单词,所以可以考虑先求解子问题. 定义状态 \(f(i)\) 表示长度为 \(i\) 的串中有多少 ...

  3. HDU 5794 A Simple Chess (容斥+DP+Lucas)

    A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...

  4. [CF1086E]Beautiful Matrix(容斥+DP+树状数组)

    给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...

  5. 【BZOJ3622】已经没有什么好害怕的了 容斥+DP

    [BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...

  6. KMP字符串匹配 模板 洛谷 P3375

    KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...

  7. $bzoj2560$ 串珠子 容斥+$dp$

    正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...

  8. 洛谷P4707 重返现世(扩展MinMax容斥+dp)

    传送门 我永远讨厌\(dp.jpg\) 前置姿势 扩展\(Min-Max\)容斥 题解 看纳尔博客去→_→ 咱现在还没搞懂为啥初值要设为\(-1\)-- //minamoto #include< ...

  9. Bzoj4753/洛谷P4432 [JSOI2016]最佳团体(0/1分数规划+树形DP)

    题面 Bzoj 洛谷 题解 这种求比值最大就是\(0/1\)分数规划的一般模型. 这里用二分法来求解最大比值,接着考虑如何\(check\),这里很明显可以想到用树形背包\(check\),但是时间复 ...

  10. [ZJOI2016]小星星(容斥+dp)

    洛谷链接:https://www.luogu.org/problemnew/show/P3349 题意相当于给一棵树重新赋予彼此不同的编号,要求树上相邻的两个节点在给定的另外一个无向图中也存在边相连. ...

随机推荐

  1. 【Android 逆向】【攻防世界】easy-dex

    这一题不easy,不知为何叫这个名字.... 1. apk 安装到手机,不知所云,各种亮瞎眼闪光 2. jadx 打开apk,一行java代码都没有,打开AndroidManifest看看 <? ...

  2. Vue框架设计:性能权衡的艺术

    "框架设计里到处都体现了权衡的艺术." 当我们设计一个框架的时候,框架本身的各个模块之间并不是相互独立的,而是相互关联.相互制约的.因此作为框架设计者,一定要对框架的定位和方向拥有 ...

  3. django中_meta组件

    # _meta组件是一个django中任何一个model类的类实例用来自省的api,简单点说,比如有一个Accounts的模型,则 Accounts._meta # 常用接口 model.Userin ...

  4. 【LeetCode栈与队列#01】队列的基本操作:用栈模拟队列和用队列模拟栈

    用栈实现队列 力扣题目链接(opens new window) 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- ...

  5. .Net之多语言配置

    介绍 支持多语言使网站可以覆盖更广泛的受众. ASP.NET Core 提供的服务和中间件可将网站本地化为不同的语言. 本次示例环境:vs2019.net5 配置 无需引用Nuget包即可实现以下功能 ...

  6. 今天接到一个根据excel来更新数据库的需求,用php写个小脚本

    需求大概内容是,excel中有些条目需要删除.有些需要新增,就需要基于这份excel生成删.增的SQL. 要求是这样的:蓝色要删除的,黄色是要新增的,白色和灰色的不用管. 我第一时间就在想:还得识别单 ...

  7. Java 辨析之实例化和初始化

    在面向对象编程中,实例化和初始化是两个相关但不同的概念: 实例化(Instantiation): 实例化是指创建一个类的新的具体对象的过程.当程序运行时,通过 new 关键字调用类的构造函数来创建该类 ...

  8. 2层for循环生成 TreeView

    C# TreeView 利用2层for循环生成,代码如下: //生成树 treeView1.Nodes.Clear(); //封装了数据库查询方法 MyDS_Grid = MyDataClass.ge ...

  9. 怎样给U盘加密

    给U盘加密其实很简单,下载一个叫U盘超级加密3000的U盘加密软件就可以了. 这款U盘加密的软件最大的特点是不用安装,只要一个exe文件.你把它放到你需要加密的U盘里,就可以加密U盘里的数据了.并且到 ...

  10. Android USB开发1—开发环境搭建

    通过Genymotion 与 VirtualBox 可以实现将电脑中的USB设备转接到Android模拟器中进行通信. Genymotion 配置 首先从https://www.genymotion. ...