CC FAVNUM (AC自动机+数位DP)
来源:互联网 发布:人工智能产业创新联盟 编辑:程序博客网 时间:2024/06/04 08:50
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
xiaodao给的题目,第一次codechef,好高端的样子。
给出一些模式串,包含至少一个模式串的为指定串。
问区间内第K个指定串。
把模式串加入到自动机中,然后可以求出区间内指定串的个数。
二分答案就行了
其实还是很水的。。。
准备准备跟着xiaodao学后缀自动机了
#include<iostream>#include<cstdio>#include<map>#include<cstring>#include<cmath>#include<vector>#include<algorithm>#include<set>#include<string>#include<queue>#define inf 100000005#define M 20005#define N 2000#define maxn 300005#define eps 1e-10#define zero(a) fabs(a)<eps#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define pb(a) push_back(a)//#define mp(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define LL long long#define MOD 1000000007#define lson step<<1#define rson step<<1|1#define sqr(a) ((a)*(a))#define Key_value ch[ch[root][1]][0]//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;struct Trie{ Trie *next[10]; Trie *fail; int isword,kind;};Trie *que[M],s[M];int idx;Trie *NewNode(){ Trie *tmp=&s[idx]; mem(tmp->next,NULL); tmp->isword=0; tmp->fail=NULL; tmp->kind=idx++; return tmp;}void Insert(Trie *root,char *s,int len){ Trie *p=root; for(int i=0; i<len; i++) { if(p->next[s[i]-'0']==NULL) p->next[s[i]-'0']=NewNode(); p=p->next[s[i]-'0']; } p->isword=1;}void Bulid_fail(Trie *root){ int head=0,tail=0; que[tail++]=root; root->fail=NULL; while(head<tail) { Trie *tmp=que[head++]; for(int i=0; i<10; i++) { if(tmp->next[i]) { if(tmp==root) tmp->next[i]->fail=root; else { Trie *p=tmp->fail; while(p!=NULL) { if(p->next[i]) { tmp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL) tmp->next[i]->fail=root; } if(tmp->next[i]->fail->isword) tmp->next[i]->isword=tmp->next[i]->fail->isword; que[tail++]=tmp->next[i]; } else if(tmp==root) tmp->next[i]=root; else tmp->next[i]=tmp->fail->next[i]; } }}char str[100];LL L,R;LL dp[20][N][2][2];int bit[25],length;LL dfs(int len,int pos,int flag,int zero,bool limit){ if(len<=0) return flag==1; if(!limit&&flag&&dp[len][pos][zero][1]!=-1) return dp[len][pos][zero][1]; if(!limit&&!flag&&dp[len][pos][zero][0]!=-1) return dp[len][pos][zero][0]; LL ans=0; int up=limit?bit[len]:9; for(int i=0; i<=up; i++) { ans+=dfs(len-1,s[pos].next[i]->kind,flag||(s[pos].next[i]->isword),0,limit&&(i==up)); } if(!limit) { dp[len][pos][zero][flag]=ans; } return ans;}LL slove(LL num){ length=0; while(num) { bit[++length]=num%10; num/=10; } return dfs(length,0,0,1,true);}LL l,r,k;LL ans;int n;void Fuck(){ LL mid,tmp=slove(l-1); while(l<=r) { mid=(l+r)>>1; if(slove(mid)-tmp>=k) { r=mid-1; ans=mid; } else l=mid+1; }}int main(){ //freopen("1.in","r",stdin); while(scanf("%lld%lld%lld%d",&l,&r,&k,&n)!=EOF) { idx=0;mem(dp,-1); Trie *root=NewNode(); for(int i=0; i<n; i++) { scanf("%s",str); Insert(root,str,strlen(str)); } Bulid_fail(root); ans=-1; Fuck(); if(ans==-1) printf("no such number\n"); else printf("%lld\n",ans); } return 0;}
- CC FAVNUM (AC自动机+数位DP)
- 【AC自动机+数位DP】SDOI2014 数数
- HDU 4518 ac自动机+数位dp
- zoj3494 BCD Code ac自动机+数位dp
- BZOJ 3530 数数【AC自动机+数位dp】
- zoj 3494(ac自动机+数位dp)
- [AC自动机+数位DP] ZOJ3494 BCD Code
- zoj3494 BCD Code(AC自动机+数位dp)
- 【bzoj3530】【sdoi2014】【数数】【AC自动机+数位dp】
- ZOJ 3494 AC自动机+数位DP
- [BZOJ3530]-[Sdoi2014]数数-AC自动机+数位DP
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- BUPT 652 Confusing Problem(AC自动机+数位DP)
- ZOJ 3494 BCD Code 数位DP+AC自动机
- ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
- 【MZ】ZOJ 3494 BCD Code AC自动机+数位DP
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ3494 BCD Code (AC自动机+数位DP)
- matlab中生成无重复随机整数的方法
- dos的疑问
- java两种实例化
- WideCharToMultiByte和MultiByteToWideChar函数的用法
- Flex As3 解析XML文件(上:基本操作)
- CC FAVNUM (AC自动机+数位DP)
- 简单插入排序和希尔排序简单应用
- Java基础语法
- java经典算法_005三元运算符
- SPFA算法
- C++中的异常处理(一)
- Android 发送短信 源代码
- 222
- Spring3.1集成hibernate3.6出现java.lang.VerifyError错误