codeforces 585F. Digits of Number Pi
来源:互联网 发布:ubuntu开机自启动mongo 编辑:程序博客网 时间:2024/05/29 10:33
AC自动机和数位dp都写挂了….我是不是该退役了…
问L~R有多少个数满足数字里包含一个长度至少为d/2的给定串的子串
如果包含了一个长度大于d/2的子串,也一定包含长度为d/2的子串
所以相当于问L~R有多少个数满足数字里包含一个长度为d/2的给定串的子串
我们把原串所有长度为d/2的子串建到AC自动机上
因为d<=50,所以点数最大不超过25000(实际上最大值应该也比这个小很多)
所以就可以直接数位dp了
f[i][j][k][x]表示dp到第i位,前面是否有前导0,前面是否顶格,走到AC自动机上的x节点的方案数
本来还要加一维表示是否已经有长度为d/2的子串了,但是我灵机一动,每个长度为d/2的子串的结束节点的所有孩子都指向他自己,就可以省掉这一维了
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxp = 110000;const int maxn = 1100;const ll Mod = 1e9+7;struct trie{ int son[10],fail;}tr[maxp]; int root,tot;bool v[maxp];void ins(char s[],const int l,const int r){ int x=root; for(int i=l;i<r;i++) { const int w=s[i]-'0'; int &y=tr[x].son[w]; if(!y) y=++tot; x=y; } v[x]=true;}char str[maxn]; int n,d;queue<int>q;void build(){ n=strlen(str); int D=d/2; root=tot=0; for(int i=0;i+D-1<n;i++) ins(str,i,i+D); q.push(root); while(!q.empty()) { const int x=q.front(); q.pop(); if(v[x]) for(int i=0;i<10;i++) tr[x].son[i]=x; else { for(int i=0;i<10;i++) { int &y=tr[x].son[i],fl=tr[x].fail; if(y) { if(x!=root) tr[y].fail=tr[fl].son[i]; q.push(y); } else y=tr[fl].son[i]; } } }}char A[maxn],B[maxn];// rol 0 upll f[2][2][2][maxp];ll cal(char s[]){ int now=0; memset(f,0,sizeof f); f[now][1][1][0]=1; for(int p=0;p<d;p++) { now=!now; for(int i=0;i<2;i++) for(int j=0;j<2;j++) { for(int x=0;x<=tot;x++) if(f[!now][i][j][x]) { ll tmp=f[!now][i][j][x]%Mod; f[!now][i][j][x]=0; int uk=j?s[p]-'0':9; for(int k=0;k<=uk;k++) { int ni=i&(k>0?0:1),nj=j&(k==uk?1:0),y=(!k&&i)?0:tr[x].son[k]; f[now][ni][nj][y]+=tmp; } } } } ll re=0; for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int x=0;x<=tot;x++) if(v[x]&&f[now][i][j][x]) (re+=f[now][i][j][x]%Mod)%=Mod; return re;}int t[maxn],tp;bool judge(int x){ int tp=0; while(x) t[++tp]=x%10,x/=10; x=root; for(int i=tp;i>=1;i--) x=tr[x].son[t[i]]; return v[x];}int main(){ scanf("%s",str); scanf("%s%s",A,B); d=strlen(A); build(); ll ans=cal(B)-cal(A); int x=root; for(int i=0;i<d;i++) x=tr[x].son[A[i]-'0']; if(v[x]) ans++; ans=(ans+Mod)%Mod; printf("%I64d\n",ans); return 0;}
阅读全文
0 0
- codeforces 585F. Digits of Number Pi
- codeforces 585F - Digits of Number Pi (dp + acauto)
- [codeforces585F/51nod1587]Digits of Number Pi
- 100,000 Digits of Pi
- Digits of PI (Part 2)
- Codeforces-260a F Adding Digits
- 翻转整数 Reverse digits of a number
- Next Number with Same Set of Digits
- Number of Parallelograms CodeForces
- codeforces#84_div2_C Lucky Sum of Digits
- codeforces 289 C Sums of Digits
- Sums of Digits - CodeForces 509 C
- Codeforces 509c Sums of Digits 贪心
- codeforces 509C Sums of Digits
- codeforces 770B Maximize Sum of Digits
- Codeforces Round #Pi (Div. 2) F. Mausoleum DP
- Codeforces Round #Pi (Div. 2) F. Mausoleum dp
- [codeforces]#350F. Restore a Number
- 表变量与临时表对比(1)
- 如何oracle查询条件里做if判断
- leetcode编程记录3 #169 Majority Element
- selenium所支持的浏览器-Safari
- hdu2433 BFS最短路
- codeforces 585F. Digits of Number Pi
- [日推荐]『装逼助手』一秒变土豪
- nutz从eclipse转idea的问题总结
- 表变量与临时表对比(2)
- Python爬虫入门-scrapy爬取唯一图库高清壁纸
- 管理和维护表
- JAVA常见问题解决办法汇总
- eval()和json.parse()的区别
- 【特斯拉组件】iOS高性能PageController