超级神题!

有n种字符,若此种字符的编号( \(1\) ~ \(n\)),\(i*2>n\),则他后面可接任意字符。若不是,则他后面接的字符编号至少要是他的两倍。

问长度为m的字符串的个数。

这道题我只想出了 \(O(n^2)\) 的做法,于是叕只能求助题解。

题解的做法和周六第二题有点像,但我并没有分析出最长链的长度小于 \(log_{2}n\) 这个性质。知道这个性质之后,就可以做了。

设 \(f[i]\) 表示长度为 \(i\) 的合法字符串的个数。\(g[i]\) 表示长度为 \(i\) 的合法链的个数。

转移就是

\[f[i]=\sum_{j=1}^{maxlen}g[j]*f[i-j]
\]

但 \(g[i]\) 并不能直接转移,所以要设个辅助状态。

设 \(p[i][j]\) 表示以 \(j\) 结尾,长度为 \(i\) 的链的个数,\(g[i]\) 就是 \(p[i]\) 里合法链的和。

\[p[i][j]=\sum_{k=1}^{j/2}p[i-1][k]
\]

这个可以用前缀和优化,也可以将式子化简为从 \(p[i][j-1]\) 转移过来。

\[p[i][j]=p[i][j-1]+p[i-1][j/2]*(j\ mod\ 2==0)
\]

总复杂度 \(O(m*log_{2}n)\)。

#include <bits/stdc++.h>
using namespace std; #define db double
#define ll long long
#define RG register inline int gi()
{
RG int ret; RG bool flag; RG char ch;
ret=0, flag=true, ch=getchar();
while (ch < '0' || ch > '9')
ch == '-' ? flag=false : 0, ch=getchar();
while (ch >= '0' && ch <= '9')
ret=(ret<<3)+(ret<<1)+ch-'0', ch=getchar();
return flag ? ret : -ret;
} const db pi = acos(-1.0);
const int N = 1e6+5, mod = 1e9+7; int f[N],g[N],p[22][N]; int main()
{
RG int n,m,len,i,j;
n=gi(), m=gi();
len=log2(n)+2;
p[1][1]=1, f[0]=1;
for (i=1; i<=len; ++i)
{
for (j=1; j<=n; ++j)
{
(p[i][j]+=p[i][j-1])%=mod;
if (j<<1 <= n)
(p[i+1][j<<1]+=p[i][j])%=mod;
else
(g[i]+=p[i][j])%=mod;
}
}
for (i=1; i<=m; ++i)
for (j=1; j<=len && j<=i; ++j)
(f[i]+=((ll)f[i-j]*g[j])%mod)%=mod;
printf("%d\n",f[m]);
return 0;
}

51nod【1196】字符串的数量的更多相关文章

  1. 51nod 1196 字符串的数量(DP+数论?)

    这题好像是神题...V1 V2 V3分别涵盖了51nod 5级算法题 6级算法题 难题 讨论区的曹鹏神牛好强啊...一种做法切了V1 V2 V3,而且做法是一步一步优化的 还没去看优化的部分,未优化已 ...

  2. 51Nod 1196 字符串的数量

    用N个不同的字符(编号1 - N),组成一个字符串,有如下要求: (1) 对于编号为i的字符,如果2 * i > n,则该字符可以作为结尾字符.如果不作为结尾字符而是中间的字符,则该字符后面可以 ...

  3. 51nod 1197 字符串的数量 V2(矩阵快速幂+数论?)

    接上一篇,那个递推式显然可以用矩阵快速幂优化...自己随便YY了下就出来了,学了一下怎么用LaTeX画公式,LaTeX真是个好东西!嘿嘿嘿 如上图.(刚画错了一发...已更新 然后就可以过V2了 or ...

  4. @51nod - 1196/1197/1198@ 字符串的数量

    目录 @description@ @solution@ @part - 1@ @part - 2@ @part - 3@ @accepted code@ @details@ @description@ ...

  5. 51nod1196 字符串的数量

    用N个不同的字符(编号1 - N),组成一个字符串,有如下要求:(1) 对于编号为i的字符,如果2 * i > n,则该字符可以作为结尾字符.如果不作为结尾字符而是中间的字符,则该字符后面可以接 ...

  6. [51nod1197]字符串的数量 V2

    用N个不同的字符(编号1 - N),组成一个字符串,有如下要求: (1) 对于编号为i的字符,如果2 * i > n,则该字符可以作为结尾字符.如果不作为结尾字符而是中间的字符,则该字符后面可以 ...

  7. 51nod 1277 字符串中的最大值

    题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #inc ...

  8. 用map来统计数组中各个字符串的数量

    1.背景 想要统计这一个字符串数组中每一个非重复字符串的数量,使用map来保存其key和value.这个需求在实际开发中经常使用到,我以前总是新建一个空数组来记录不重复字符串,并使用计数器计数,效率低 ...

  9. 51Nod 1277 字符串中的最大值(KMP,裸题)

    1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: ...

随机推荐

  1. VELT-0.1.5开发:在VS2013下进行python开发

    快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 本文仅适用于vs20 ...

  2. storm - 可靠机制

    一 可靠性简单介绍                    Storm的可靠性是指Storm会告知用户每个消息单元是否在一个指定的时间(timeout)内被全然处理. 全然处理的意思是该MessageI ...

  3. LeetCode Hash Table 3. Longest Substring Without Repeating Characters

    HashMap的应用可以提高查找的速度,键key,值value的使用拜托了传统数组的遍历查找方式,对于判断一个字符或者字符串是否已经存在的问题可以非常好的解决.而本题需要解决的问题就是判断新遍历到的字 ...

  4. versions 忽略 xcuserdata 目录

    1.打开versions,选中xcuserdata目录 2.菜单条.Action->ignore "..." 3.versions不再显示不同

  5. 15:取近似值ApproximateValue

    题目描述 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值.如果小数点后数值大于等于5,向上取整:小于5,则向下取整. 输入描述:输入一个正浮点数值 输出描述:输出该数值的近似整数值 输入例子 ...

  6. Bootstrp--一个导航面板切换的实用例子

    <!--导航区开始--> <ul class="nav nav-tabs nav-stacked" role="tablist"> &l ...

  7. android开发系列之ContentObserver

    在这篇博客里面我想要分享一下自己最近在项目里面遇到一个比较好的数据同步解决方案,首先让我们先来看看该方案的应用场景:我们在客户端本地利用数据库缓存了一些数据,当我们检测到数据库里面的数据发生变化的时候 ...

  8. HDFS源码分析DataXceiver之整体流程

    在<HDFS源码分析之DataXceiverServer>一文中,我们了解到在DataNode中,有一个后台工作的线程DataXceiverServer.它被用于接收来自客户端或其他数据节 ...

  9. 解决ListView滑动时出现黑边的问题

    [声明]转载请注明出处,此文出自指尖飞落的博客:http://blog.csdn.net/huntersnail --尊重作者,知识无价.交流无限! 两种方法 1.代码去边缘线 myList.setF ...

  10. 【打CF,学算法——一星级】Codeforces Round #313 (Div. 2) A. Currency System in Geraldion

    [CF简单介绍] 提交链接:http://codeforces.com/contest/560/problem/A 题面: A. Currency System in Geraldion time l ...