2019.02.15 codechef Favourite Numbers(二分+数位dp+ac自动机)
传送门
题意:
给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自动机)的更多相关文章
- 咕咕(数位dp+AC自动机)
咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...
- CF 434C Tachibana Kanade's Tofu[数位dp+AC自动机]
Solution //本代码压掉后两维 #include<cstdio> #define max(a,b) (a<b?b:a) using namespace std; inline ...
- [Sdoi2014]数数[数位dp+AC自动机]
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 834 Solved: 434[Submit][Status][ ...
- shuoj 1 + 2 = 3? (二分+数位dp)
题目传送门 1 + 2 = 3? 发布时间: 2018年4月15日 22:46 最后更新: 2018年4月15日 23:25 时间限制: 1000ms 内存限制: 128M 描述 埃森哲是 ...
- POJ3208 Apocalypse Someday(二分 数位DP)
数位DP加二分 //数位dp,dfs记忆化搜索 #include<iostream> #include<cstdio> #include<cstring> usin ...
- 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 ...
- CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)
传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...
- Balanced Numbers (数位dp+三进制)
SPOJ - BALNUM 题意: Balanced Numbers:数位上的偶数出现奇数次,数位上的奇数出现偶数次(比如2334, 2出现1次,4出现1次,3出现两次,所以2334是 Balance ...
- Codeforces #55D-Beautiful numbers (数位dp)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
随机推荐
- 涂抹mysql笔记-mysql数据库文件结构
<>初始化选项文件:默认位置:windows平台 windir\my.ini windir可通过echo $WINDIR$查看 系统盘的根目录即:c:\my.ini installdir\ ...
- sql server 数据库变成单用户模式的恢复
USE master;GODECLARE @SQL VARCHAR(MAX);SET @SQL=''SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID)FROM master. ...
- webservice的简单使用,cxf框架的的使用
Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布 ...
- 【Selenium】各种方式在选择的时候应该怎么选择
最后再总结一下,各种方式在选择的时候应该怎么选择: 1. 当页面元素有id属性时,最好尽量用id来定位.但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法. ...
- cv2的安装
第一种 ,直接尝试 pip install cv2 ,大可能报错. 第二种,pip install opencv-python ,大概率 直接成功. 第三种 ,去网上下包 放到 sit_package ...
- java.io.UnsupportedEncodingException
启动项目抛错: java.io.UnsupportedEncodingException: 1 at java.lang.StringCoding.decode(StringCoding.java:1 ...
- Sphinx 安装与使用
Sphinx 优点 高速索引(接近10M/S) 高速搜索(2-4G文本搜索耗时不到0.1秒) 高可用性(单CPU支持100GB文本,100M文档) 提供相关性排名.分布式搜索.文档摘要(高亮显示) S ...
- Elasticsearch **代码片段
```JAVA BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); RangeQueryBuilder createTimeQuery ...
- C#对接JAVA系统遇到的AES加密坑
起因对接合作伙伴的系统,需要对数据进行AES加密 默认的使用了已经写好的帮助类中加密算法,发现结果不对,各种尝试改变加密模式改变向量等等折腾快一下午.最后网上查了下AES在JAVA里面的实现完整代码如 ...
- linux shell并发执行命令
一般我们在linux上十一shell命令的批量执行操作,一般使用for或者while 循环进行操作,但是这样有一个问题,for或者while本质上是串行的,并不能,如果某一个命令执行耗费的时间比较长, ...