传送门

题意:

给444个整数L,R,K,nL,R,K,nL,R,K,n,和nnn个数字串,L,R,K,数字串大小≤1e18,n≤65L,R,K,数字串大小\le1e18,n\le65L,R,K,数字串大小≤1e18,n≤65

问[L,R][L,R][L,R]中第KKK小的拥有nnn个数字串中至少一个串作为子串的数。


思路:

一看就要二分答案,现在考虑统计[L,R][L,R][L,R]中有多少个满足题意的数。

不妨考虑数位dpdpdp,然后发现没法很好的转移,为了优化转移可以对于所有的数字串构建一个acacac自动机来优化转移。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=2005;
typedef long long ll;
namespace acam{
	int ch[N][10],fail[N],tot=0,q[N],hd,tl;
	bool exi[N];
	#define idx(x) ((x)^48)
	inline void init(){memset(ch[0],0,sizeof(ch[0])),memset(fail,0,sizeof(fail)),exi[0]=0,tot=0;}
	inline int build(){return exi[++tot]=0,memset(ch[tot],0,sizeof(ch[tot])),tot;}
	inline void insert(char s[]){
		int p=0,n=strlen(s);
		for(ri x,i=0;i<n;++i){
			if(!ch[p][(x=idx(s[i]))])ch[p][x]=build();
			p=ch[p][x];
		}
		exi[p]=1;
	}
	inline void getfail(){
		hd=1,tl=0;
		for(ri i=0;i<10;++i)if(ch[0][i])q[++tl]=ch[0][i];
		while(hd<=tl){
			int p=q[hd++];
			for(ri i=0,v;i<10;++i){
				if((v=ch[p][i]))fail[v]=ch[fail[p]][i],q[++tl]=v,exi[v]|=exi[fail[v]];
				else ch[p][i]=ch[fail[p]][i];
			}
		}
	}
	#undef idx
}
namespace dDP{
	ll f[20][N][2];
	vector<int>Up,Down;
	inline vector<int>init(ll x){
		vector<int>ret;
		ret.clear();
		if(!x)return ret.push_back(x),ret;
		while(x)ret.push_back(x-x/10*10),x/=10;
		return ret;
	}
	inline ll dfs(int pos,int sta,bool flag,bool down,bool up,bool zero){
		if(pos==-1)return flag;
		if(!up&&!down&&!zero&&~f[pos][sta][flag])return f[pos][sta][flag];
		ll ret=0;
		for(ri l=down?Down[pos]:0,r=up?Up[pos]:9,i=l;i<=r;++i){
			if(zero&&!i&&pos)ret+=dfs(pos-1,0,flag,down&&i==l,up&&i==r,1);
			else ret+=dfs(pos-1,acam::ch[sta][i],flag|acam::exi[acam::ch[sta][i]],down&&i==l,up&&i==r,zero&&!i);
		}
		if(!up&&!down&&!zero)f[pos][sta][flag]=ret;
		return ret;
	}
	inline ll solve(ll l,ll r){
		int len1,len2;
		Down=init(l),len1=Down.size();
		Up=init(r),len2=Up.size();
		for(ri i=len1+1;i<=len2;++i)Down.push_back(0);
		return dfs(Up.size()-1,0,0,1,1,1);
	}
}
char s[100];
int main(){
	ll a,b,K,l,r,ans;
	int n;
	cin>>a>>b>>K>>n;
	acam::init();
	while(n--)scanf("%s",s),acam::insert(s);
	acam::getfail();
	l=a,r=b+1,ans=b+1;
	memset(dDP::f,-1,sizeof(dDP::f));
	while(l<=r){
		ll mid=l+r>>1;
		if(dDP::solve(a,mid)<K)l=mid+1;
		else r=mid-1,ans=mid;
	}
	if(ans==b+1)puts("no such number");
	else cout<<ans;
	return 0;
}

2019.02.15 codechef Favourite Numbers(二分+数位dp+ac自动机)的更多相关文章

  1. 咕咕(数位dp+AC自动机)

    咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...

  2. CF 434C Tachibana Kanade's Tofu[数位dp+AC自动机]

    Solution //本代码压掉后两维 #include<cstdio> #define max(a,b) (a<b?b:a) using namespace std; inline ...

  3. [Sdoi2014]数数[数位dp+AC自动机]

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 834  Solved: 434[Submit][Status][ ...

  4. shuoj 1 + 2 = 3? (二分+数位dp)

    题目传送门 1 + 2 = 3? 发布时间: 2018年4月15日 22:46   最后更新: 2018年4月15日 23:25   时间限制: 1000ms   内存限制: 128M 描述 埃森哲是 ...

  5. POJ3208 Apocalypse Someday(二分 数位DP)

    数位DP加二分 //数位dp,dfs记忆化搜索 #include<iostream> #include<cstdio> #include<cstring> usin ...

  6. Codeforces Round #460 (Div. 2) B Perfect Number(二分+数位dp)

    题目传送门 B. Perfect Number time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

    传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...

  8. Balanced Numbers (数位dp+三进制)

    SPOJ - BALNUM 题意: Balanced Numbers:数位上的偶数出现奇数次,数位上的奇数出现偶数次(比如2334, 2出现1次,4出现1次,3出现两次,所以2334是 Balance ...

  9. Codeforces #55D-Beautiful numbers (数位dp)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. 从OsChina Git下载项目到MyEclipse中

    前提是,拥有权限下载 1.进入MyEclipse,点击File-->Import,选择Git,点击“Next”,如下图: , 2.选择“URI”,点击"Next" 3.输入项 ...

  2. Cache基本原理之:结构

    转载自:https://www.jianshu.com/p/2b51b981fcaf Cache entries 数据在主存和缓存之间以固定大小的”块(block)”为单位传递,也就是每次从main ...

  3. android 开发 View _9_ 实现渐变功能(直线与圆形)

    参考博客:https://blog.csdn.net/iispring/article/details/50500106/ android颜色渐变的分类有: LinearGradient线性渐变 线性 ...

  4. java反编译工具cfr

    http://www.benf.org/other/cfr/ 下载反编译工具 @echo off SET home=%cd% rem 指定存放jar包的目录 SET jar_dir=%home%\ja ...

  5. 给tableView设置背景图片

    经常遇到要给tableView设置背景图片的问题,但如果直接设置背景  backgroundView的话,背景图不会显示,原因是  tableView上的cell默认是不透明的颜色,所以解决方法是 让 ...

  6. SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)

    1.概念:Restful 基础架构 2.具体内容 对于 Rest 基础架构实现处理是 SpringCloud 核心所在,其基本操作形式在 SpringBoot 之中已经有了明确的讲解,那么本次为 了清 ...

  7. try、catch、finally都有return语句时执行哪个

    任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话.如果finally中有return语句,那么程序就return了,所以finally中 ...

  8. Python : *args和**kwargs是什么东东呢?

    def foo(*args, **kwargs): print 'args = ', args print 'kwargs = ', kwargs print '------------------- ...

  9. 一个linux bbr存在的调用顺序bug

    最近跟踪bbr的状态转换的代码,发现一个问题: [,min_rtt_us=,full_bw=,cycle_idx=,pacing_gain=,cwnd_gain=,rtt_cnt= [,min_rtt ...

  10. canvas刮刮乐游戏等

    裁剪 ctx.clip():当前路径外的区域不再绘制 <canvas id="cans" width=500 height=500></canvas> &l ...