《Vuejs设计与实现》第 16 章(解析器) 上 - 教程
目录
16.1 文本模式及其对解析器的影响
16.2 递归下降算法构造模板 AST
16.3 状态机的开启与停止
解析器本质是一个状态机,正则也是一个状态机,本章使用正则完成一个 html 解析器。
16.1 文本模式及其对解析器的影响
文本模式是解析器工作时的特殊状态。
在这些状态下,解析器的解析行为会有所不同。解析器会根据遇到的特殊标签切换工作模式,从而改变对文本的解析方式:
- 当遇到
<title>
标签、<textarea>
标签,当解析器遇到这两个标签时,会切换到RCDATA
模式。 - 当遇到
<style>
、<xmp>
、<iframe>
、<noembed>
、<noframes>
、<noscript>
等标签,当解析器遇到这些标签时,会切换到RAWTEXT
模式。 - 当解析器遇到
<![CDATA[
字符串时,会进入 CDATA 模式。
默认情况下,解析器的初始模式是 DATA 模式。
Vue.js 的模板 DSL 中不允许出现 <script>
标签,当 Vue.js 模板解析器在遇到 <script>
标签时会切换到 RAWTEXT
模式。
解析器根据当前的工作模式,采用不同的解析行为。
例如,在默认的 DATA 模式下,解析器会在遇到 < 字符时,切换到标签开始状态(tag open state),从而能够解析标签元素。
在该模式下,如果遇到 & 字符,解析器会切换到字符引用状态(character reference state),也就是可以处理 HTML 字符实体的状态。
然而,在 RCDATA 模式下,解析器的行为会有所不同。在这种模式下,解析器遇到 < 字符时,将会切换到 RCDATA less-than sign state 状态,而不是标签开始状态。
在 RCDATA less-than sign state 状态下,如果遇到 / 字符,会直接切换到 RCDATA 的结束标签状态(RCDATA end tag open state);否则,会将 < 字符视为普通字符处理,然后继续处理后续字符。这就是为什么在 <textarea>
标签内,可以将 < 字符作为普通文本,解析器并不会将其解析为标签开始的标志。
以下是一个示例:
helloworld
在上述 HTML 代码中,虽然 <textarea>
标签内存在 <div>
标签,但解析器并不会将 <div>
解析为标签元素,而是作为普通文本处理。
然而,需要注意的是,尽管在 RCDATA 模式下,解析器不能识别标签元素,但它仍然支持 HTML 字符实体。当解析器遇到 & 字符时,会切换到字符引用状态。例如:
©
浏览器在渲染这段 HTML 代码时,会在文本框内展示字符 ©。
解析器在 RAWTEXT 模式下的工作方式与 RCDATA 模式类似,不同之处在于 RAWTEXT 模式下不再支持 HTML 实体,而是将其作为普通字符处理。
Vue.js的单文件组件的解析器在遇到 <script>
标签时会进入 RAWTEXT 模式,将<script>
标签内的内容作为普通文本处理。CDATA
模式在 RAWTEXT
模式的基础上更进一步,在 CDATA
模式下,解析器将把任何字符都作为普通字符处理,直到遇到 CDATA
的结束标志为止。
PLAINTEXT 模式与 RAWTEXT 模式类似,但解析器一旦进入 PLAINTEXT 模式,将不会再退出。
不同的模式及各其特性:
不同解析器,还会影响对终止解析的判断,后文具体讨论,我们先将上述模式定义为状态表:
const TextModes = {
DATA: 'DATA',
RCDATA: 'RCDATA',
RAWTEXT: 'RAWTEXT',
CDATA: 'CDATA',
}
16.2 递归下降算法构造模板 AST
这节我们实现一个更完善的模板解析器,基本架构模型如下:
// 定义文本模式,作为一个状态表
const TextModes = {
DATA: 'DATA',
RCDATA: 'RCDATA',
RAWTEXT: 'RAWTEXT',
CDATA: 'CDATA',
}
// 解析器函数,接收模板作为参数
function parse(str) {
// 定义上下文对象
const context = {
// source 是模板内容,用于在解析过程中进行消费
source: str,
// 解析器当前处于文本模式,初始模式为 DATA
mode: TextModes.DATA,
}
// 调用 parseChildren 函数开始进行解析,它返回解析后得到的子节点
// parseChildren 函数接收两个参数:
// 第一个参数是上下文对象 context
// 第二个参数是由父代节点构成的节点栈,初始时栈为空
const nodes = parseChildren(context, [])
// 解析器返回 Root 根节点
return {
type: 'Root',
// 使用 nodes 作为根节点的 children
children: nodes,
}
}
上述代码,首先定义 TextModes 描述预定义的文本模式。
然后我们定义 parse 解析函数,其中定义上下文对象 context 用来维护执行程序时产生的各种状态。
接着,调用 parseChildren 函数进解析返回解析后得到的子节点,并使用这些子节点作为 children 来创建 Root 根节点。
这段代码与第 15 章不同,在第 15 章中,我们首先对模板内容进行标记化得到一系列 Token,然后根据这些 Token 构建模板 AST。
实际上,创建 Token 与构造模板 AST 的过程可以同时进行,因为模板和模板 AST 具有同构的特性。
上面代码 parseChildren 函数是核心,后续会不断调用它来消费模板内容,它会返回解析后得到的子节点,举个例子,假如有以下模板:
1
2
parseChildren 函数在解析这段模板后,会得到由这两个 <p>
节点组成的数组:
[
{ type: 'Element', tag: 'p', children: [/*...*/] },
{ type: 'Element', tag: 'p', children: [/*...*/] },
]
之后,这个数组将作为 Root 根节点的 children。
parseChildren 函数接收两个参数。
- 第一个参数:上下文对象 context。
- 第二个参数:由父代节点构成的栈,用于维护节点间的父子级关系。
parseChildren 函数本质上也是一个状态机,该状态机有多少种状态取决于子节点的类型数量。在模板中,元素的子节点有几种:
- 标签节点,例如
<div>
。 - 文本插值节点,例如 {{ val }}。
- 普通文本节点,例如:text。
- 注释节点,例如
<!---->
。 - CDATA 节点,例如
<![CDATA[ xxx ]]>
。
在标准的 HTML 中,节点的类型将会更多,例如 DOCTYPE 节点等。为了降低复杂度,我们仅考虑上述类型的节点。
parseChildren 函数在解析模板过程中的状态迁移过程:
- 当遇到字符
<
时,进入临时状态。 - 如果下一个字符匹配正则 /a-z/i,则认为这是一个标签节点,于是调用 parseElement 函数完成标签的解析。注意正则表达式 /a-z/i 中的 i,意思是忽略大小写(case-insensitive)。
- 如果字符串以
<!--
开头,则认为这是一个注释节点,于是调用 parseComment 函数完成注释节点的解析。 - 如果字符串以
<![CDATA[
开头,则认为这是一个 CDATA 节点,于是调用 parseCDATA 函数完成 CDATA 节点的解析。 - 如果字符串以
{{
开头,则认为这是一个插值节点,于是调用 parseInterpolation 函数完成插值节点的解析。 - 其他情况,都作为普通文本,调用 parseText 函数完成文本节点的解析。
具体代码,我们还需要结合文本模式:
function parseChildren(context, ancestors) {
// 定义 nodes 数组存储子节点,它将作为最终的返回值
let nodes = []
// 从上下文对象中取得当前状态,包括模式 mode 和模板内容 source
const { mode, source } = context
// 开启 while 循环,只要满足条件就会一直对字符串进行解析
// 关于 isEnd() 后文会详细讲解
while (!isEnd(context, ancestors)) {
let node
// 只有 DATA 模式和 RCDATA 模式才支持插值节点的解析
if (mode === TextModes.DATA || mode === TextModes.RCDATA) {
// 只有 DATA 模式才支持标签节点的解析
if (mode === TextModes.DATA && source[0] === '<') {
if (source[1] === '!') {
if (source.startsWith('
相关文章:
《Vuejs设计与实现》第 16 章(解析器) 上 - 教程
《Vuejs设计与实现》第 16 章(解析器) 上 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospac…...
go代码(1)
package main import "fmt" func main() { fmt.Println("hello world") } 运行: $ go run hello-world.go hello world $ go build hello-world.go $ ls hello-world hello-world.go $ ./hello-world hello world本文来自博客园,作者:gosamuel,转载…...
7种常见的入侵检测系统规避技术解析
本文详细解析了攻击者常用的7种入侵检测系统(IDS)规避技术,包括文件恶意软件、混淆技术、IP分片、源路由等,并提供了相应的缓解措施,帮助企业安全团队加强网络防护。7种常见的入侵检测系统规避技术 恶意攻击者使用各种规避策略渗透网络,而入侵检测系统(IDS)却未能察觉。了解…...
js的引用
js代码 JavaScript又称ECMAScript,常用的版本通常有es5以及es6 元素中的代码 a元素除了能定义链接地址,同样可以定义js <a href="javascript:window.alert(hello)">Hello</a>我们可以通过按钮的单击事件实现上面相同的效果,其中事件也就是什么情况下执…...
P3957 [NOIP 2017 普及组] 跳房子
题目描述 给出 \(n\) 个点的坐标 \(a_i\) 和权值 \(s_i\),每次向右移动正距离 \(p\),满足 \(d-x \le p \le d+x\) 且落在给定的点上,求使经过点值的最大和不小于 \(k\) 的最小 \(x\)。 思路 step1-二分答案 这道题我们要求的是最小的 \(x\),可显然我们无法将 \(x\) 设计到状…...
C++中常用的STL容器
C++中常用的STL容器: Vector:变长数组:数组长度是可以动态变化的,倍增 Pair<X,Y>:二元组:前后两个元素类型可以不同 string:字符串:常见的函数:substr()截取一段字串,c_str()返回字符串的头指针 queue:队列:先进先出,push()插入,pop() 弹出,front() 返回…...
我的数据科学探索之旅:从兴趣到公考与学习计划
一.关于我:不止于代码的多面手我的兴趣:在热爱里收获成长 生活中的我,总喜欢在艺术相关的领域折腾。从初中开始,我就爱上了跳舞,第一次跟着视频练基础动作时,肢体僵硬得像 “机器人”,连简单的 wave 都做不流畅,反复练习后还总跟不上节奏。但我没放弃,每周坚持练 3 …...
MySQL 核心记录解析:从配置到存储的 “说明书 + 记录仪” 系统
MySQL 核心记录解析:从配置到存储的 “说明书 + 记录仪” 系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New&quo…...
JavaScript Array 对象
JavaScript 中的 Array 对象是用于存储多个值的特殊类型的对象。 Array 是按顺序存储元素的,可以根据索引(从 0 开始)来访问它们。 创建数组 可以通过几种方式创建数组: 使用 Array 构造函数: let arr1 = new Array(3); // 创建一个长度为 3 的空数组 let arr2 = new Arr…...
代码规范
C++ 编码规范 一 版式 1.程序块缩进 4 个空格,只能使用空格键,不能使用 TAB 键。 2.相对独立的程序块之间、变量说明之后必须加空行,函数之间也用空行分开。 3.一行只写一条语句,if、for、do、while 等语句自占一行,且执行语句部分无论多少都要加括号 {}。 4.代码行之内应…...
mac远程连接windows
安装 Windows App 在app store 中安装windows app添加pcip可以在windows 电脑的终端上键入ipconfig查看ipv4地址。 双击连接 凭据是windows电脑的账户跟密码,例如Administrator,password 要求是在同一局域网内! 在mac终端上ping一下windows的ip看能否ping的通就知道了。...
子类不依赖泛型,重写父类方法,通过强制类型转换父类方法参数出现的问题。——— 一个例子引发的思考
使用泛型(推荐)public interface FlowHandlerGateway<P extends FlowApprovalPageCondition> {Page<FlowApprovalPage> pageQuery(P condition); }//父类 @Slf4j @Component @RequiredArgsConstructor public class FlowHandlerGatewayImpl<P extends FlowApp…...
WebStorm代码一键美化
还在手动调整代码格式?还在为团队代码风格不统一而头疼? 相信很多朋友都遇到过这样的痛苦场景:写完代码一团糟,看着就难受 团队成员代码风格千差万别,维护起来要命 每次提交代码前都要手动整理格式,费时费力上一篇《10分钟搞定Vue3项目》已经搭建好了项目基础架构,脚手架…...
3分钟搞定Vue组件库
还在为写前端页面发愁?还在为设计按钮、表格这些基础组件浪费时间? 经过上一篇《WebStorm代码一键美化》的学习,相信你已经掌握了 Prettier、ESLint、TypeScript 这三大开发神器。 今天,我要教你一个更厉害的招式:3分钟搞定高颜值UI组件库!学会这一招,你的前端开发效率将…...
Golang中设置HTTP请求代理的策略
在Golang中设置HTTP请求代理涉及 net/http包中的 http.Transport结构体,它控制着HTTP请求的细节。要定义代理,可以使用 http.ProxyURL函数配合 url.Parse函数来创建一个 url.URL对象,然后将该对象赋值给 Transport结构体的 Proxy字段。 以下是配置HTTP代理的典型步骤:引入必…...
[开源免费] iGTTS(Gemini TTS) 文本转语音(TTS)的命令行工具。
iGTTS(Gemini TTS) iGTTS(Gemini TTS) 开源免费的文本转语音(TTS)的命令行工具。 iGTTS(Gemini TTS) 是通过调用 Gemini TTS 的接口,实现文本转语音(TTS)的命令行工具。 添加 API key # 编辑 .zshrc: vim ~/.zshrc# 添加信息(导入环境变量): export GEMINI_API_KEY=&l…...
结合Spring和MyBatis实现DAO层操作综述
在Java企业级开发中,Spring框架和MyBatis持久层框架的结合使用已成为常见模式。下面进行详细介绍如何结合这两个框架实现DAO层(数据访问层)操作。 首先,我们需要明确Spring框架和MyBatis的角色定位。Spring是一个全方位的企业级开发框架,提供了包括但不限于依赖注入、事务…...
202205_CHIMA_follow
流量分析,CHIMA,应急响应,文件拼接Tags:流量分析,CHIMA,应急响应 0x00. 题目 附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件 附件名称:202205_CHIMA_follow.zip发起攻击的IP地址受到攻击的资产的IP+Port上传的木马完整路径上传的文…...
Lua脚本协助Redis分布式锁实现命令的原子性
在实现Redis分布式锁的过程中,Lua脚本的使用可以确保命令的原子性,这是因为Redis会将整个Lua脚本执行作为一个不可分割的整体,从而在多客户端环境中保证数据的一致性和安全性。 分布式锁通常是为了在不同进程或服务器间同步访问共享资源。在Redis中,SETNX命令可以用来实现锁…...
快读快写 学习笔记
在OI中,经常有输入输出量巨大的题,这一类题一般需要非常快速的输入输出方式,于是便有了快读快写 下面是模板(原理无需理解,用的时候直接复制上就行): #include <cstdio> #include <cctype> using namespace std; int precision=-1; char buf[100000],*p1=bu…...
Ubuntu 安装 CLion
下载网址:https://www.jetbrains.com/clion/download/?section=linux 安装在 /opt/clion: sudo mkdir /opt/clion 将安装包解压到 /opt/clion: sudo tar -zxvf CLion-2025.2.1.tar.gz -C /opt/clion ls /opt/clion/clion-2025.2.1这样就安装好了。 启动: sh /opt/clion/cl…...
AI编程实战
不久前我用trace体验了一把AI编程,完成了一个股票交易记录软件的开发,这次有个紧急项目,有了上次的AI编程实践,我决定让AI编程帮我一把 工具选择 上次说千问没有IDE,但阿里云出了一个Qoder,在这个紧急项目之前,我刚好开始使用Qoder,接到紧急项目的时候,是时候让AI真正…...
25/9/13(补)
做了下20年csps的单选,错了两道,后边随机跳题了个之前wa的题(p7777 shelter),数学标签,有编号1~n的石子,用两种抓取方式吧石子抓完,第一种抓法是选一个数i把第i堆石子抓走,代价为ip。第二种是选两个数i,j,把第i,j堆石子抓走,代价为|i-j|q。 发现性质: 第一,二种方…...
面向对象编程(OOP)的原则
面向对象编程(OOP)的原则面向对象编程有一系列核心原则,这些原则指导着我们如何设计高质量、可维护和可扩展的软件系统。这些原则可以分为两大类:基本特性和设计原则。 一、面向对象编程的四大基本特性(基石) 1. 封装 (Encapsulation) 核心思想:将数据和对数据的操作捆绑…...
【龙智Atlassian插件】Confluence周报插件上线AI智能总结,一键生成专业报告 - 实践
【龙智Atlassian插件】Confluence周报插件上线AI智能总结,一键生成专业报告 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &q…...
数字化(管理)系统的工具化思考
一、引言:数字化转型的背景与逻辑 进入 21 世纪,信息技术、互联网、大数据、人工智能与物联网的迅速发展,使得企业与组织的运作方式发生了深刻变革。管理学界普遍认为,传统的经验管理与制度管理正逐步向 数字化管理系统 过渡。这不仅是工具更迭的问题,更是认知范式、管理模…...
详细介绍:传统神经网络实现-----手写数字识别(MNIST)项目
详细介绍:传统神经网络实现-----手写数字识别(MNIST)项目pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New",…...
C#语言中使用using关键字
在 C# 语言中,“using”关键字被用于不同的上下文和目的,它的用法大体上可以被分为三类:导入命名空间、简化资源管理和提供别名。 首先,"using"关键字最常见的用途是导入命名空间。这在 C# 程序中非常普遍,因为它可以允许程序员引用命名空间中定义的类型,而不需…...
中育新版本OSS Token获取API分析
中育新版本OSS Token获取API分析 在8/28更新中(或更早),中育彻底停用了旧版本的GenerateTokenAsyncAPI,转而使用GenerateTokenV2AsyncAPI,新的API使用了签名和一些不明所以的参数,并可能限制了可以上传的路径。 为了尽快迁移旧的工具、程序,我对web端的OSS逻辑进行了分析。…...
25/9/12(补,上一篇是9/11的)
把昨天没改完的码积木改完了,最终解法先发现一个性质是往上堆一个就算和下一个高度重叠也对下一个没有影响,所升序排完后设变量m(m初始等于a[1]),如果m比当前遍历到的a[i]大代表这个a[i]有重叠,更新答案,如果比a[i]小就让m=a[i]保持同频。 改完这题后又去改暑假的T3,就是…...
动态编译 vs. 静态编译,容器时代那个更有优势?
动态编译 vs. 静态编译,容器时代那个更有优势?一、动态编译 vs. 静态编译:一场关于“依赖”的战争 要理解静态编译,我们首先要明白它的对立面——动态编译,这也是 C、C++ 以及 Java、Python、C#、Ruby 等大多数主流语言所采用的方式。 1. 动态编译:运行时“借”东西 想象…...
实用指南:操作系统类型全解析:从批处理到嵌入式
实用指南:操作系统类型全解析:从批处理到嵌入式pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace…...
【C++ 类和对象・高阶深化(下)】再探构造函数(含初始化列表),吃透 static 成员、友元、内部类及对象拷贝编译器优化 - 指南
【C++ 类和对象・高阶深化(下)】再探构造函数(含初始化列表),吃透 static 成员、友元、内部类及对象拷贝编译器优化 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…...
2
C++ 数据结构数组 链表 队列 堆 树 map/set hashmysql 索引 索引就像是数据的目录。索引的好处就是可以提高查询速度,但是会占用物理空间,而且创建和维护索引要耗费时间,每次进行增删改操作都需要动态维护。索引的分类数据结构:B+ 树索引,hash,full-text物理存储:聚簇索…...
VSCode 运行 C/C++ 程序
VSCode 安装插件:重点参考: https://blog.csdn.net/icacxygh001/article/details/120981354 https://code.visualstudio.com/docs/cpp/config-linux#_running-the-build...
3 字节
进程与线程的区别 线程是轻量级进程,每个进程中都有唯一的主线程,主线程和进程是相互依存的关系。进程是资源分配和拥有的基本单位;线程是系统调度的基本单位进程拥有CPU 资源,内存资源,文件资源,句柄等;线程拥有程序计数器,寄存器,栈和状态字切换情况:进程由操作系统…...
Springcloud Alibaba(一)
一、什么是Springcloud Alibaba它是微服务概念的一种实现,解决了如下问题N个服务,如何管理?(服务治理 注册中心【服务的注册、发现、删除】)nacos N个服务,如何通信?feign N个服务,客户端如何访问?gateway N个服务,一旦出现问题了,怎么处理?(容错)sentinel N个服…...
111111111
1111111111...
202204_DASCTF_SimpleFlow
流量分析,DASCTF,WebShell,蚁剑AntSwordTags:流量分析,DASCTF,WebShell,蚁剑AntSword 0x00. 题目 附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件 附件名称:202204_DASCTF_SimpleFlow.zip 0x01. WP 1. 分析http协议,找到附件数据 …...
使用 Winscope 跟踪窗口转换
Winscope 是一款 Web 工具,可以让用户在动画和转换期间和之后记录、重放和分析多个系统服务的状态。Winscope 将所有相关的系统服务状态记录在一个跟踪文件中。使用带有跟踪文件的 Winscope 界面,您可以通过重放、单步执行和调试过渡来针对每个动画帧检查这些服务的状态(无论…...
25/9/12(补)
做了下19csps初试,60多分,记不清了,反正能过,写完后改一道暑假没过的题,没改完就下课了...
深入解析:“纳米总管”——Arduino Nano 的趣味生活
深入解析:“纳米总管”——Arduino Nano 的趣味生活pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monosp…...
洛谷题目难度系统优化
以下为优化后的难度系统:优化后难度 对应KaTex数学公式\(\color{FE4C61}{{入门}}\) \color{FE4C61}{{入门}}\(\color{F39C11}{{普及-}}\) \color{F39C11}{{普及-}}\(\color{FFC116}{{普及}}\) \color{FFC116}{{普及}}\(\color{FFD700}{{普及+}}\) \color{FFD700}{{普及+}}\(\c…...
202112_摆烂杯_WhatAHack!
流量分析Tags:流量分析,CTFSHOW 0x00. 题目 这是你沐师傅的站的流量,最近你沐师傅去跟着某讯搭了一个WP平台后发了一篇文章再测试了一下自己的网站就再也没去管过平台了。结果被某位名字貌似大概可能叫g4_simon的大黑阔给hack掉了网站,并进行了一些操作拿到了沐师傅放在平台里…...
少儿 500 常用汉字 字帖
500 常用汉字 每个字加入拼音 每个字加入笔画笔顺 少儿楷书练习下载链接如下 1-4画 5画 6画 7画 8画 9画 10画 11-16画...
Ubuntu 安装 gcc
命令 gcc --version 或者 gcc -v 能查看 gcc 版本。 未安装:安装命令: sudo apt update # 更新软件包源 sudo apt-get install build-essential gdb这样,GCC 就安装完成了。...
Redis常见性能问题
常见性能问题和解决方案?Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。 如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。 为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。 尽量避…...
3 线性模型
目录P22 P22 复习一下: 假设同类别之间的数据是比较相似的,所以在空间里,同类别的数据是挨在一起的。那么假设现在有一个超平面去进行二分类,由于一个类别的数量多得多而且两个类别的权重是一样的,于是超平面就可以把很多少数类分为正数类而且损失函数的值要下降(看P12,…...
详细介绍:七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线
详细介绍:七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New",…...
P3522 [POI 2011] TEM-Temperature
题目描述 给出 \(n\) 个数所在区间,求最长可能不降区间。 思路 首先,我们要解决不降的问题,如何才能保证两个相邻区间选数可能不降,不难发现,只要前一个数的最大值大于等于后一个数的最小值即可,即 \(r_{i-1} \ge l_i\)。 然后,因为我们要求的是一段一段连续的区间,所以…...