清北学堂模拟赛d6t3 反击数


分析:显然是一道数位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 反击数的更多相关文章
- 清北学堂模拟赛day7 数字碰撞
/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...
- 清北学堂模拟赛d4t1 a
分析:大模拟,没什么好说的.我在考场上犯了一个超级低级的错误:while (scanf("%s",s + 1)),导致了死循环,血的教训啊,以后要记住了. /* 1.没有发生改变, ...
- 清北学堂模拟赛day7 错排问题
/* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...
- 清北学堂模拟赛day7 石子合并加强版
/* 注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化 */ #include<iostream> #include<cstdio&g ...
- 清北学堂模拟赛d6t6 棋盘迷宫
3.棋盘迷宫(boardgame.pas/c/cpp)(boardgame.in/out)时间限制:5s/空间限制:256M[题目描述]小 A 和小 Z 是非常要好的朋友, 而且他们都对迷宫游戏非常有 ...
- 清北学堂模拟赛d1t2 火柴棒 (stick)
题目描述众所周知的是,火柴棒可以拼成各种各样的数字.具体可以看下图: 通过2根火柴棒可以拼出数字“1”,通过5根火柴棒可以拼出数字“2”,以此类推. 现在LYK拥有k根火柴棒,它想将这k根火柴棒恰好用 ...
- 清北学堂模拟赛d1t1 位运算1(bit)
题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值.假设数字N的价值是K,LYK想找到一个 ...
- 清北学堂模拟赛d2t6 分糖果(candy)
题目描述总共有n颗糖果,有3个小朋友分别叫做L,Y,K.每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感.也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果 ...
- 清北学堂模拟赛d2t5 吃东西(eat)
题目描述一个神秘的村庄里有4家美食店.这四家店分别有A,B,C,D种不同的美食.LYK想在每一家店都吃其中一种美食.每种美食需要吃的时间可能是不一样的.现在给定第1家店A种不同的美食所需要吃的时间a1 ...
随机推荐
- 03、HelleBaiduMap
D:\百度地图\百度地图\资料\百度地图与定位SDK\百度地图v3.5.0\BaiduMap_AndroidSDK_v3.5.0_All\BaiduMap_AndroidSDK_v3.5.0_Docs ...
- Linux必知必会的目录结构
1.目录结构 /bin 二进制文件 命令 /sbin 超级命令 只有root用户可以使用 /boot 系统的引导文件 系统内核 /dev 设备文件 光盘 硬盘分区 /etc 系统配置文件 /home ...
- E20171006-hm
trace vt. 跟踪,追踪; 追溯,探索; 探索; 查找; vi. 沿着一小径或道路前进; 可以追溯的; n. 痕迹; 痕迹,踪迹; 微量,极少量; [植 ...
- Golang 入门 : goroutine(协程)
在操作系统中,执行体是个抽象的概念.与之对应的实体有进程.线程以及协程(coroutine).协程也叫轻量级的线程,与传统的进程和线程相比,协程的最大特点是 "轻"!可以轻松创建上 ...
- BZOJ 2178 Simpson积分
思路: 我发现能用Simpson积分水的题 好像都是裸题诶233333 //By SiriusRen #include <bits/stdc++.h> using namespace s ...
- Codeforces 763A
乍看之下感觉有点无从下手,,其实是个很简单的水题,陷入僵局 题目大意:给一棵树,树上每个节点都染色,问能否取下一个节点,使得剩余所有子树上的点的颜色都相同.能输出YES和取下的节点编号,否则输出NO. ...
- gerrit项目配置
1. 相关约定说明: 1.1 gerrit服务器ip地址:192.168.130.10 1.2 gerrit服务器端用户名:gerrit 1.3 gerrit用户端管理员:admin 1.4 ssh端 ...
- Linq学习(零)-错误汇总
问题一: Cannot execute text selection: CS0009 Metadata file 'C:\Users\Kimisme\Documents\LINQPad Plugins ...
- 协程概念,原理及实现(c++和node.js实现)
协程 什么是协程 wikipedia 的定义: 协程是一个无优先级的子程序调度组件,允许子程序在特点的地方挂起恢复. 线程包含于进程,协程包含于线程.只要内存足够,一个线程中可以有任意多个协程,但某一 ...
- 表格对象的获取和更改(原生js)
表格对象的获取 var oT = document.getElementById("tb"); //获取head console.log(oT.tHead); console.lo ...