分析:显然是一道数位dp题,不过需要一些奇怪的姿势.常规的数位dp能统计出一个区间内满足条件的数的个数,可是我们要求第k个,怎么办呢?转化为经典的二分问题,我们二分当前数的大小,看它是第几大的,就可以了.

显然数位dp套上模板,再用上kmp的next数组就可以了,传递4个参数:还剩下多少位没有匹配,匹配了多少位,是否达到上限和是否匹配成功,到最后判断一下就可以了.

学到了一种很强的思想:如果能求出i是第几个数,要求出第k个数就可以二分i的值.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; long long L, R, K, f[][][];
int m, nextt[], a[];
char X[]; void init()
{
nextt[] = ;
nextt[] = ;
for (int i = ; i < m; i++)
{
int j = nextt[i];
while (j && X[i] != X[j])
j = nextt[j];
nextt[i + ] = X[i] == X[j] ? j + : ;
}
} long long dfs(int len, int w, bool limit, bool flag)
{
if (len == )
return flag;
if (!limit && f[len][w][flag] != -)
return f[len][w][flag];
int maxn = limit ? a[len] : ;
long long cnt = ;
for (int i = ; i <= maxn; i++)
{
int t = w;
while (t && X[t] - '' != i)
t = nextt[t];
if (X[t] - '' == i)
t++;
cnt += dfs(len - , t, limit && (i == a[len]), flag || (t == m));
}
return limit ? cnt : f[len][w][flag] = cnt;
} long long query(long long u)
{
int cnt = ;
while (u)
{
a[++cnt] = u % ;
u /= ;
}
memset(f, -, sizeof(f));
return dfs(cnt, , , );
} int main()
{
scanf("%lld %lld %s %lld", &L, &R, X, &K);
m = strlen(X);
init();
if (query(R) < K + query(L - ))
{
printf("Hey,wake up!\n");
return ;
}
long long t = query(L - ),ans = L;
long long l = L, r = R;
while (l < r)
{
long long mid = (l + r) >> ;
if (query(mid) - t >= K)
{
r = mid;
ans = mid;
}
else
l = mid + ;
}
printf("%lld\n", r); return ;
}

清北学堂模拟赛d6t3 反击数的更多相关文章

  1. 清北学堂模拟赛day7 数字碰撞

    /* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...

  2. 清北学堂模拟赛d4t1 a

    分析:大模拟,没什么好说的.我在考场上犯了一个超级低级的错误:while (scanf("%s",s + 1)),导致了死循环,血的教训啊,以后要记住了. /* 1.没有发生改变, ...

  3. 清北学堂模拟赛day7 错排问题

    /* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...

  4. 清北学堂模拟赛day7 石子合并加强版

    /* 注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化 */ #include<iostream> #include<cstdio&g ...

  5. 清北学堂模拟赛d6t6 棋盘迷宫

    3.棋盘迷宫(boardgame.pas/c/cpp)(boardgame.in/out)时间限制:5s/空间限制:256M[题目描述]小 A 和小 Z 是非常要好的朋友, 而且他们都对迷宫游戏非常有 ...

  6. 清北学堂模拟赛d1t2 火柴棒 (stick)

    题目描述众所周知的是,火柴棒可以拼成各种各样的数字.具体可以看下图: 通过2根火柴棒可以拼出数字“1”,通过5根火柴棒可以拼出数字“2”,以此类推. 现在LYK拥有k根火柴棒,它想将这k根火柴棒恰好用 ...

  7. 清北学堂模拟赛d1t1 位运算1(bit)

    题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值.假设数字N的价值是K,LYK想找到一个 ...

  8. 清北学堂模拟赛d2t6 分糖果(candy)

    题目描述总共有n颗糖果,有3个小朋友分别叫做L,Y,K.每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感.也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果 ...

  9. 清北学堂模拟赛d2t5 吃东西(eat)

    题目描述一个神秘的村庄里有4家美食店.这四家店分别有A,B,C,D种不同的美食.LYK想在每一家店都吃其中一种美食.每种美食需要吃的时间可能是不一样的.现在给定第1家店A种不同的美食所需要吃的时间a1 ...

随机推荐

  1. [linux环境配置]个人用持续更新ing~

    alias ll='ls -la' export PATH=$PATH:~/Desktop/myscript alias gpush='git push origin HEAD:refs/for/ma ...

  2. bzoj1098

    并查集+dfs 先开始想和不相连的点用并查集连起来,最后看每个连通块有多少个点就行了,但是这样是O(n*n)的,然而我并没有想到补图 其实就是求补图有多少连通块,因为补图中两个点有边,那么这两个点必须 ...

  3. Redis学习和应用记录(2)--常用数据类型及命令

    这一节主要介绍Redis支持的数据结构及常用命令. 数据类型 Redis支持多种数据类型的存储,包括字符,列表,集合,有续集合,哈希表,bit数组,超级日志等.下面分别介绍: strings:存储普通 ...

  4. Git文件不显示图标/标识

    初次使用Git服务功能,做了很多探路事情,记录下刚刚遇到的问题 情况:安装了Git应用程序,或者也安装了TortoiseGit-1.8.16.0-64bit(类似SVN工具)后,上传下载文件没有问题, ...

  5. Linux命令补充及基础优化。

    1.用户部分 1.1 创建新用户 涉及命令 useradd [root@oldboyedu-50 ~]# useradd oldboy #添加用户 oldboy 1.2 设置密码 [root@oldb ...

  6. Magnetic Storms

    http://acm.timus.ru/problem.aspx?space=1&num=1126 简单的线段树求区间最值 #include <stdio.h> #include ...

  7. js中的slice()、substring()、substr()、split()、join()、indexof()

    在js中字符截取函数有常用的三个slice().substring().substr()了,下面我来给大家介绍slice().substring().substr()函数在字符截取时的一些用法与区别吧 ...

  8. SRAM and DRAM

    DRAM:(Dynamic Random Access Memory)动态随机访问存储器,只能将数据保存较短的时间.每隔一段时间需要对数据进行刷新一次,没有刷新的单元数据会丢失.常见的用途是作为内存( ...

  9. 我的周记1——”云想衣裳花想容"

    这里记录过去一周,我学习到的,思考的,看到的,每周五发布. http 网上参考http入门协议  https://juejin.im/post/5afad7f16fb9a07abf72ac30 超文本 ...

  10. 修路方案 Kruskal 之 次小生成树

    次小生成树 : Kruskal 是先求出来  最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...