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 ...
随机推荐
- Salesforce LWC学习(四十) dynamic interaction 浅入浅出
本篇参考: Configure a Component for Dynamic Interactions in the Lightning App Builder - Salesforce Light ...
- SpringBoot 解决跨域问题代码
package com.example.demo.gs; import org.springframework.context.annotation.Configuration; import jav ...
- UBOOT编译--- make xxx_deconfig过程详解(一)
make xxx_deconfig过程详解 1. 前言 2. 概述 3. build变量的定义 4. 目标%config的定义 4.1 依赖 scripts_basic 4.1.1 语句$(if $ ...
- webpack4--按需加载
在做单页面应用的过程中,通常利用webpack打包文件,将依赖的外部问价单独打一个vendor.js.这样就会有个问题,这个文件会随着你引用的包的增多,体积会越来越大.在路由中利用import 引用文 ...
- 数组去重函数(unique)
题目链接 stl中的一员大将:unique 也就是去重,通俗来讲,这个玩应的用法一般是 unique(数组名,数组名+大小)(没错和sort几乎一模一样) 然后值得注意的有两点:第一点:在unique ...
- Training: Stegano I
原题链接:http://www.wechall.net/challenge/training/stegano1/index.php 很明显,这是一道图像隐写题,因为他说的 我们右键图片,点击其他窗口打 ...
- Android开发之线程间通信
Android开发之线程间通信 当我们的软件启动的时候,计算机会分配进程给到我们运行的程序,在进程中包含多个线程用于提高软件运行速度. 在android网络请求中,我们知道在日常开发中不能在子线程中跟 ...
- 打印三位数的水仙花数Java
public class Flower{ //水仙花数就是一个 个位数的立方+十位数的立方+百位数的立方=这个三位数 //153 = 1*1*1+5*5*5+3*3*3 public static v ...
- Django基础笔记2(分页)
Django Django自带的分页功能 from django.core.paginator import Paginator # 用于分页 curPage = request.GET.get('p ...
- JDK中内嵌JS引擎介绍及使用
原文: JDK中内嵌JS引擎介绍及使用 - Stars-One的杂货小窝 最近研究阅读这个APP,其主要功能就是通过一个个书源,从而实现移动端阅读的体验 比如说某些在线小说阅读网站,会加上相应的广告, ...