CF1051E Vasya and Big Integers
[CF1051E Vasya and Big Integers](Problem - E - Codeforces)
sb的做法
单调队列乱整(
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5,MOD=998244353;
int n,len1,len2;
string s,l,r;
int q[N],st=1,ed,us=1;
bool ck_l(string t){
if(t.size()<l.size()) return true;
if(t.size()>l.size()) return false;
return t<l;
}
bool ck_r(string t){
if(t.size()<r.size()) return false;
if(t.size()>r.size()) return true;
return t>r;
}
bool check(int st,int ed){
string t=s.substr(st,ed-st+1);
// cout<<st<<" "<<ed<<" "<<t<<" "<<((t<l)?1:0)<<" "<<((t>r)?1:0)<<" "<<((t[0]=='0')?1:0)<<endl;
return ck_l(t)||ck_r(t)||(t[0]=='0'&&st!=ed);
}
ll dp[N],sum=1;
int main(){
char t;
cin>>s,cin>>l,cin>>r;
// cout<<"\n-------"<<r<<"------"<<endl;
s='#'+s;
n=s.size()-1,dp[0]=1;
for(int i=1;i<=n;++i){
q[++ed]=i;
while(st<=ed&&check(q[st],i)) (sum+=-dp[q[st]-1]+MOD)%=MOD,++st;
if(st>ed) return printf("0"),0;
while(us<ed&&us<st) ++us,(sum+=dp[q[us]-1])%=MOD;
while(us+1<=ed&&!check(q[us+1],i)) ++us,(sum+=dp[q[us]-1])%=MOD;
dp[i]=sum;
// cout<<i<<" "<<st<<" "<<us<<" "<<ed<<" "<<dp[i]<<endl;
}
printf("%lld\n",dp[n]);
return 0;
}
大概思路:
用一个单调队列来维护当前可以选择用来当最后一段的开头的所有下标
然后因为新加的点不一定能马上用到(因为有下限),所以除了st
、ed
外还有us
区间[st,us]
就是可以用的下标
不过这是戳的,下辈子有空再弄吧。。。
正解
算出s
与l
和r
的\(extend\),然后就可以进行\(DP\)了
在\(DP\)中,算出可以转移到i的下标取值范围\([l1,r1]\)
可以先得出一个大概的范围:\([i+len_l-1,i+len_r-1]\),因为当前划分出来的字符串的长度的范围为[len1,len2]
倒着\(DP\),\(dp[i]\)表示以i开头有多少种划分方式
然后如果\(s\)与\(l\)不相等的第一个位置上,\(l\)较大,则说明当前划分出来的字符串的长度至少为\(len_l+1\);如果\(s\)与\(l\)不相等的第一个位置上,\(r\)较小,则说明当前划分出来的字符串的长度最大为\(len_r-1\)
然后前缀和优化,这道题就G了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5,MOD=998244353;
int n,len1,len2,nxt1[N],nxt2[N],extend1[N],extend2[N];
char s[N],l[N],r[N];
void exkmp(char s[],int n,int nxt[]){
nxt[1]=n;
for(int i=2,a=0,p=0;i<=n;++i){
if(i<p) nxt[i]=min(nxt[i-a+1],p-i);
while(i+nxt[i]<=n&&s[nxt[i]+1]==s[i+nxt[i]]) ++nxt[i];
if(i+nxt[i]>p) p=i+nxt[i],a=i;
}
}
void ekp(char s[],char t[],int n,int m,int nxt[],int extend[]){
for(int i=1,a=0,p=0;i<=n;++i){
if(i<p) extend[i]=min(nxt[i-a+1],p-i);
while(i+extend[i]<=n&&extend[i]+1<=m&&s[i+extend[i]]==t[extend[i]+1]) ++extend[i];
if(i+extend[i]>p) p=i+extend[i],a=i;
}
}
ll dp[N],sum[N];
int main(){
scanf("%s\n%s\n%s",s+1,l+1,r+1);
n=strlen(s+1),len1=strlen(l+1),len2=strlen(r+1);
exkmp(l,len1,nxt1),exkmp(r,len2,nxt2);
ekp(s,l,n,len1,nxt1,extend1),ekp(s,r,n,len2,nxt2,extend2);
sum[n+1]=dp[n+1]=1;
for(int i=n;i;--i){
if(s[i]=='0') dp[i]=(l[1]=='0')*dp[i+1];
else{
int l1=i+len1-1,r1=i+len2-1;
if(extend1[i]<len1&&l[extend1[i]+1]>s[i+extend1[i]]) ++l1;
if(extend2[i]<len2&&r[extend2[i]+1]<s[i+extend2[i]]) --r1;
r1=min(r1,n);
if(l1>r1) dp[i]=0;
else dp[i]=((sum[l1+1]-sum[r1+2])%MOD+MOD)%MOD;
}
sum[i]=(dp[i]+sum[i+1])%MOD;
}
printf("%lld",dp[1]);
return 0;
}
CF1051E Vasya and Big Integers的更多相关文章
- Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement
1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...
- Codeforces 1051E. Vasya and Big Integers
题意:给你N个点M条边,M-N<=20,有1e5个询问,询问两点的最短距离.保证没有自环和重边. 题解:连题目都在提示你这个20很有用,所以如果是颗树的话那任意两点的最短距离就是求一下lca搞一 ...
- CF_EDU51 E. Vasya and Big Integers
传送门:https://codeforces.com/contest/1051/problem/E 题意: 把一个数分成许多小段,每一段的值在L和R间.问有多少种分法. 思路 : 首先,需要快速处理出 ...
- CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )
题意:给定字符串S,A,B.现在让你对S进行切割,使得每个切割出来的部分在[A,B]范围内,问方案数. 思路:有方程,dp[i]=Σ dp[j] (S[j+1,i]在合法范围内). 假设M和 ...
- ExKMP(Z Algorithm) 讲解
目录 问题引入 CaiOJ 1461 [EXKMP]最长共同前缀长度 算法讲解 匹配过程 next 的求解 复杂度证明 代码解决 一些例题 UOJ #5. [NOI2014]动物园 CF1051E V ...
- 2018SDIBT_国庆个人第一场
A - Turn the Rectangles CodeForces - 1008B There are nn rectangles in a row. You can either turn eac ...
- 2018.9.20 Educational Codeforces Round 51
蒟蒻就切了四道水题,然后EF看着可写然而并不会,中间还WA了一次,我太菜了.jpg =.= A.Vasya And Password 一开始看着有点虚没敢立刻写,后来写完第二题发现可以暴力讨论,因为保 ...
- CF 1008C Reorder the Array
You are given an array of integers. Vasya can permute (change order) its integers. He wants to do it ...
- DP 题集 2
关于 DP 的一些题目 String painter 先区间 DP,\(dp[l][r]\) 表示把一个空串涂成 \(t[l,r]\) 这个子串的最小花费.再考虑 \(s\) 字符串,\(f[i]\) ...
- CodeForces Educational Codeforces Round 51 (Rated for Div. 2)
A:Vasya And Password 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen(&q ...
随机推荐
- 六、模型层(ORM)
六.模型层(ORM) Django中内嵌了ORM框架,不需要直接编写SQL语句进行数据库操作,而是通过定义模型类,操作模型类来完成对数据库中表的增删改查和创建等操作. O是object,也就类对象的意 ...
- 下一代工具链「GitHub 热点速览 v.22.43」
作为一个前端工程师,你这周被下一代的前端工具链 Turbo 刷屏了吗?不只是 Turbo 这个小工具,作为一个社区生产力工具,本周思否还开源了他们的问答系统 answer,能直接用上相关的技术标签也省 ...
- ES6 学习笔记(十一)迭代器和生成器函数
1.前言 JavaScript提供了许多的方法来获取数组或者对象中的某个元素或者属性(迭代).从以前的for循环到之后的filter.map再到后来的for...in和for...of的迭代机制.只要 ...
- The Google File System 翻译和理解
The Google File System 摘要 GFS 是一个可扩展的分布式文件系统,用于大型分布式数据密集型应用上.它可以运行在便宜的普通硬件上,提供了高性能和一定的容错性. 1. 分布式文件系 ...
- Educational Codeforces Round 130 (Rated for Div. 2) C. awoo's Favorite Problem
https://codeforc.es/contest/1697/problem/C 因为规则中,两种字符串变换都与'b'有关,所以我们根据b的位置来进行考虑: 先去掉所有的'b',如果两字符串不相等 ...
- android_studio 使用
android studio安装 目前使用: android studio 4.1.3 Zip免安装版:android-studio-ide-201.7199119-windows413.zip an ...
- java学习之spring基础
0x00前言 spring框架应用的是ioc模式,ioc模式是指控制反转模式,本质是你不去创建对象让spring框架给你创建对象你去使用对象.多种开发模式通过配置文件和注解的方式去开发的都很值得去学习 ...
- java学习之JSON
0X00前言 JSON可以说是javascript的一种数据类型,我们学习JSON是为了在客户端的数据给读取出来,官方的解释是:概述:JSON(JavaScript Object Notation, ...
- MongoDB - 入门指南
组件结构 核心进程 在 MongoDB 中,核心进程主要包含了 mongod.mongos 和 mongosh 三个. 其中最主要的是 mongod 程序,其在不同的部署方案中(单机部署.副本集部署. ...
- windows查看端口和杀掉端口
//执行下面命令 netstat --help 获取netstat的所有命令参数 //例如查看8080端口占用 netstat -ano | findstr 8080 //查看该端口是什么 taskl ...