2024牛客(4)K题

登录—专业IT笔试面试备考平台_牛客网

using i64 = long long;
using ll = long long;
constexpr ll M = 1e9 + 7;
template<class Info>
struct SegmentTree {int n;std::vector<Info> info;SegmentTree() : n(0) {}SegmentTree(int n_, Info v_ = Info()) {init(n_, v_);}template<class T>SegmentTree(std::vector<T> init_) {init(init_);}void init(int n_, Info v_ = Info()) {init(std::vector<Info>(n_, v_));}template<class T>void init(std::vector<T> init_) {n = init_.size();info.assign(4 << (int)std::log2(n), Info());std::function<void(int, int, int)> build = [&](int p, int l, int r) {if (r - l == 1) {info[p] = init_[l];return;}int m = (l + r) / 2;build(2 * p, l, m);build(2 * p + 1, m, r);pull(p);};build(1, 0, n);}void pull(int p) {info[p] = info[2 * p] + info[2 * p + 1];}void modify(int p, int l, int r, int x, const Info& v) {if (r - l == 1) {info[p] = v;return;}int m = (l + r) / 2;if (x < m) {modify(2 * p, l, m, x, v);}else {modify(2 * p + 1, m, r, x, v);}pull(p);}void modify(int p, const Info& v) {modify(1, 0, n, p, v);}Info rangeQuery(int p, int l, int r, int x, int y) {if (l >= y || r <= x) {return Info();}if (l >= x && r <= y) {return info[p];}int m = (l + r) / 2;return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 0, n, l, r);}template<class F>int findFirst(int p, int l, int r, int x, int y, F pred) {if (l >= y || r <= x || !pred(info[p])) {return -1;}if (r - l == 1) {return l;}int m = (l + r) / 2;int res = findFirst(2 * p, l, m, x, y, pred);if (res == -1) {res = findFirst(2 * p + 1, m, r, x, y, pred);}return res;}template<class F>int findFirst(int l, int r, F pred) {return findFirst(1, 0, n, l, r, pred);}template<class F>int findLast(int p, int l, int r, int x, int y, F pred) {if (l >= y || r <= x || !pred(info[p])) {return -1;}if (r - l == 1) {return l;}int m = (l + r) / 2;int res = findLast(2 * p + 1, m, r, x, y, pred);if (res == -1) {res = findLast(2 * p, l, m, x, y, pred);}return res;}template<class F>int findLast(int l, int r, F pred) {return findLast(1, 0, n, l, r, pred);}
};struct Info {ll a;//表示黄色砖块,当前ll b;ll c = 1;ll d;
};Info operator+(const Info& b, const Info& a) {//b.a + a.a * b.c//b.b + a.a * b.d + a.b //a.c * b.c//a.c * b.d + a.d return { (b.a + ((a.a%M) * (b.c%M))%M)%M, (b.b + ((a.a%M) * (b.d%M)) + a.b)%M, ((a.c%M) * (b.c%M))%M, (((a.c%M) * (b.d%M)%M) + a.d)%M };
}Info Y{ 0, 0, 1, 1 };
Info B{ 1, 0, 0, 1 };//箭头指向下一个位置
Info R{ 0, 0, 2, 1 };//总数量乘以2在加上一个红色砖块int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int n, q;std::cin >> n >> q;std::string s;std::cin >> s;//最底层的n个区间,比如[0,1)表示第一个区间,代表第一块砖SegmentTree<Info> seg(n);for (int i = 0; i < n; i++) {seg.modify(i, (s[i] == 'Y') ? Y : ((s[i] == 'B') ? B : R));/*for (int j = 0; j < n; j++) {Info t = seg.rangeQuery(j, j + 1);std::cout <<j<<":"<< t.a << ' ' << t.b << ' ' << t.c << ' ' << t.d << '\n';}*/}while (q--) {int o;std::cin >> o;if (o == 1) {int p;char c;std::cin >> p >> c;p--;seg.modify(p, (c == 'Y') ? Y : ((c == 'B') ? B : R));}else {int l, r;std::cin >> l >> r;l--;Info res = seg.rangeQuery(l, r);//b和d的和为总数ll ans = (res.b + res.d) % M;std::cout << ans << "\n";}}return 0;
}

第一点:std::vector<Info> info;存的是按区间字符操作后的效果,有点难理解,举个例子,如果你查询[0,1)这个区间相当于查询按第一个字符进行游戏后的效果,如果第一个字符是Y,那么查询的结果就是Info Y{ 0, 0, 1, 1 };至于Info为什么要这么定义我们来看看下面的内容.

其中最难理解的就是下面这一部分

struct Info {ll a;//最左边的柱子的倍数ll b;//所有累计的方块ll c = 1;//现有倍数ll d;//现有这一列的方块
};Info operator+(const Info& b, const Info& a) {//b.a + a.a * b.c//b.b + a.a * b.d + a.b//a.c * b.c//a.c * b.d + a.d return { (b.a + ((a.a%M) * (b.c%M))%M)%M, (b.b + ((a.a%M) * (b.d%M)) + a.b)%M, ((a.c%M) * (b.c%M))%M, (((a.c%M) * (b.d%M)%M) + a.d)%M };
}Info Y{ 0, 0, 1, 1 };
Info B{ 1, 0, 0, 1 };//箭头指向下一个位置
Info R{ 0, 0, 2, 1 };//总数量乘以2在加上一个红色砖块

首先a,b,c,d的意思我都标出来了,为什么要这么定义呢,我们这样想,当中间有很多个操作B出现的时候,那么这个区间是不是有很多个柱子,这样不清楚,让我来画个图

如果产生了多个柱子是不是说明有操作B,第一个柱子不管是YRRY或是什么其它的操作它都不可能产生第二个柱子.假如我们要合并两个区间,

每根柱子表示的无非就是YR的组合,可能是YYYY,RRRR又或者是YRRY等等,不存在B所以最后一根和第一根合并的序列一定是一根,那么效果是怎样的呢, 显然最后一根总方块数我们可以设为k,那么合并后可以表示为((k+a1)*2+a2)*2+a3,原先第一根的方块数为(a1*2+a2)*2+a3,两者的差值不就是把k提到外面来吗及(a1*2+a2)*2+a3+4*k(注意,我只是举了一个只有两个R情况下的例子,*2的数量要根据R的数量来定),那么+重载为什么这样运算也很明显了.

对于第一个算式b.a + a.a * b.c,再使用B之前,第一根的方块数量和R的数量是不确定的,如果第一个区间有B,那么第一个区间的c变量是0,也就是说两个区间合并后的第一根倍数就是b.a,如果第一个区间没有B,说明第二个区间的第一根和第一个区间合并后会变成一根,即b.c不为0而b.a为0,合并后的第一根是a.a乘以b.c.

感觉解释的不是很清楚(*/ω\*),换个解释方法,Info Y{ 0, 0, 1, 1 };第一个1表示当前倍数为自己身的一倍,也就是不翻倍,第二个1表示添加到目前这根柱子里添加一个方块,Info R{ 0, 0, 2, 1 };翻倍后添加,Info B{ 1, 0, 0, 1 };这涉及到好几个运算,首先看最简单的a.c*b.c表示第一根柱子已经固定了,根据之前讲的最后一根和第一根合并的运算,我们要把当前倍数转移到a变量里,及a.a * b.c,因为b是左边的区间,所以按照这个运算,如果它在之前有过B字符,那么它也不为0,所以要加上b.a.

列举了两个,其它的是一样的,就像是自动机一样,涉及到有B和没B的情况,比较难解释,当涉及B的时候某些变量会自动变为0从而做出变换.

b.a(有B/没B) + a.a(有B/没B) * b.c(没B/有B)
b.b(有B/没B) + a.a(有B/没B) * b.d + a.b(有B/没B)         有Ba.a会把b.d添加到非当前柱子
a.c * b.c(没B/有B)
a.c(没B/有B) * b.d + a.d        没有B的时候a.c会把b.d添加到当前柱子 

大概就是这样,尽力了,很难解释.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue样式绑定

1. 绑定 HTML class ①通过class名称的bool值判断样式是否被启用 <template><!--通过样式名称是否显示控制样式--><div :class"{ haveBorder: p.isBorder, haveBackground-color: p.isBackgroundcolor }">此处是样式展示区域</div><br /…

Linux篇:开发工具yum/vim/gcc/g++/Makefile/gdb

一. yum&#xff1a;软件包管理器 什么是软件包&#xff1f; 在Linux 下安装软件 , 一个通常的办法是下载到程序的源代码 , 并进行编译 , 得到可执行程序 . 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好 , 做成软件包 (可以理解成windows 上的安装程序) 放在…

内网穿透的应用-如何本地部署Elasticsearch搜索分析引擎实现并发布公网远程访问

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

探索Flask框架:打造优雅而强大的Web应用

在当今互联网时代&#xff0c;Web应用的需求日益增长&#xff0c;而作为开发者&#xff0c;我们需要一个简洁明快、灵活可扩展的框架来满足这些需求。Flask框架作为一个Python微型框架&#xff0c;在其简洁的设计理念和丰富的扩展生态系统之间找到了完美的平衡&#xff0c;为我…

防御保护第六次作业

需求: 8&#xff0c;分公司内部的客户端可以通过域名访问到内部的服务器 9&#xff0c;假设内网用户需要通过外网的web服务器和pop3邮件服务器下载文件和邮件&#xff0c;内网的FTP服务器也需要接受外网用户上传的文件。针对该场景进行防病毒的防护。 10&#xff0c;我们需要针…

C++模板从入门到入土

1. 泛型编程 如果我们需要实现一个不同类型的交换函数&#xff0c;如果是学的C语言&#xff0c;你要交换哪些类型&#xff0c;不同的类型就需要重新写一个来实现&#xff0c;所以这是很麻烦的&#xff0c;虽然可以cv一下&#xff0c;有了模板就可以减轻负担。 下面写一个适…

基于springboot+vue的中小企业设备管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

H 桥逆变方式介绍(双极性)

单极性控制和双极性控制是说IGBT四个管子的控制 前面所说的单极性控制是其中一个管子开通、关闭另外一个管子持续开通 而双极性是四个管子中的两个管子同时导通&#xff0c;同时关断。彼此交替变化 所以当方波出现低电平时&#xff0c;是一对管子同时导通&#xff0c;出现高电…

2.21 Qt day2 菜单栏/工具栏/状态栏/浮动窗口、UI界面、信号与槽

思维导图 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;…

golang实现延迟队列(delay queue)

golang实现延迟队列 1 延迟队列&#xff1a;邮件提醒、订单自动取消 延迟队列&#xff1a;处理需要在未来某个特定时间执行的任务。这些任务被添加到队列中&#xff0c;并且指定了一个执行时间&#xff0c;只有达到指定的时间点时才能从队列中取出并执行。 应用场景&#xff1…

智慧驿站_智慧文旅驿站_轻松的驿站智慧公厕_5G智慧公厕驿站_5G模块化智慧公厕

多功能城市智慧驿站是在智慧城市建设背景下&#xff0c;所涌现的一种创新型社会配套设施。其中&#xff0c;智慧公厕作为城市智慧驿站的重要功能基础&#xff0c;具备社会配套不可缺少的特点&#xff0c;所以在应用场景上&#xff0c;拥有广泛的需求和要求。那么&#xff0c;城…

#12解决request中getReader()和getInputStream()只能调用一次的问题

目录 1、背景 2、解决方案 2.1、自定义HttpServletRequestWrapper 2.2、JsonRequestHeaderParamsHelper 2.3、HttpServletRequestReplacedFilter 2.4、使用 1、背景 当前系统Content-Type为application/json&#xff0c;参数接收方式采用RequestBody和RequestParam&#…

平时积累的FPGA知识点(10)

平时在FPGA群聊等积累的FPGA知识点&#xff0c;第10期&#xff1a; 41 ZYNQ系列芯片的PL中使用PS端送过来的时钟&#xff0c;这些时钟名字是自动生成的吗&#xff1f; 解释&#xff1a;是的。PS端设置的是ps_clk&#xff0c;用report_clocks查出来的时钟名变成了clk_fpga_0&a…

Linux篇:进程

一. 前置知识 1.1冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系 为什么计算机要采用冯诺依曼体系呢&#xff1f; 在计算机出现之前有很多人都提出过计算机体系结构&#xff0c;但最…

时序数据库TimescaleDB,实战部署全攻略

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

C++ Primer 笔记(总结,摘要,概括)——第5章 语句

目录 5.1 简单语句 5.2 语句作用域 5.3 条件语句 5.3.1 if语句 5.3.2 switch语句 5.4 迭代语句 5.4.1 while语句 5.4.2 传统的for语句 5.4.3 范围for语句 5.4.4 do while语句 5.5 跳转语句 5.5.1 break语句 5.5.2 continue语句 5.5.3 goto语句 5.6 try语句块和异常处理 5…

2024华北医院信息网络大会第二轮更新通知

大会背景 近年来&#xff0c;我国医疗行业信息化取得了飞跃式的发展&#xff0c;医疗信息化对医疗行业有着重要的支撑作用。2021年国家卫健委、中医药管理局联合印发《公立医院高质量发展促进行动&#xff08;2021-2025年&#xff09;》&#xff0c;提出重点建设“三位一体”智…

【青龙】快速搭建青龙面板,部署属于你自己的应用!

青龙面板是一个支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台。 废话不多说&#xff0c;直接开始。 这里使用一台 雨云 的云服务器作为演示。雨云注册地址&#xff1a;https://www.rainyun.com/ 优惠码&#xff1a;lz932 使用优惠码注册后绑定微信可获得8折…

【Chrono Engine学习总结】4-vehicle-4.3-两个vehicle碰撞测试

由于Chrono的官方教程在一些细节方面解释的并不清楚&#xff0c;自己做了一些尝试&#xff0c;做学习总结。 今天突发奇想&#xff0c;想试一下&#xff0c;是否可以实现两个vehicle的碰撞&#xff1f; 1、两辆vehicle的仿真 官方提供了demo_VEH_TwoCars这个demo&#xff0c…

C++入门04 函数的参数传递、引用类型与重载

图源&#xff1a;文心一言 听课笔记简单整理&#xff0c;供小伙伴们参考&#xff0c;包含以下内容“&#x1f40b;3.11 引用类型、&#x1f40b;3.14 内联函数、&#x1f40b;3.15 默认参数值、&#x1f40b;3.16 函数重载、&#x1f40b;3.17 C系统函数”~&#x1f95d;&…