[luogu P3797] 妖梦斩木棒 [线段树]
题目背景
妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力。
题目描述
有一天,妖梦正在练习剑术。地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段。现在这个木棒可以看做由三种小段构成,中间的n-2段都是左右都被切断的断头,我们记做’X’,最左边的一段和最右边的一段各有一个圆头,记做’(‘和’)’。幽幽子吃饱后闲来无事,决定戏弄一下妖梦。她拿来了许多这样的三种小段木棒,来替换掉妖梦切下来的n段中的一部分,然后问妖梦一些问题。这些操作可以这样描述:
1 x C 将第x个小段的木棒替换成C型,C只会是’X’,’(‘,’)’中的一种
2 l r 询问妖梦从第l段到第r段之间(含l,r),有多少个完整的木棒
完整的木棒左右两端必须分别为’(‘和’)’,并且中间要么什么都没有,要么只能有’X’。
虽然妖梦能够数清楚这些问题,但幽幽子觉得她回答得太慢了,你能教给妖梦一个更快的办法吗?
输入输出格式
输入格式:
第一行两个整数n,m,n表示共有n段木棒,m表示有m次操作。
木棒的初始形状为(XXXXXX......XXXXXX)。
接下来m行,每行三个整数/字符,用空格隔开。第一个整数为1或2,表示操作的类型,若类型为1,则接下来一个整数x,一个字符C。若类型为2,接下来两个整数l,r。含义见题目描述。
输出格式:
对于每一个操作2,输出一行一个整数,表示对应询问的答案。
输入输出样例
- 4 4
- 2 1 4
- 2 2 4
- 1 2 (
- 2 2 4
- 1
- 0
- 1
说明
对于30%的数据,1<=n,m<=1000
对于100%的数据,1<=n,m<=200000
by-orangebird
十分可爱的线段树题啊QAQ
造一棵线段树,维护
1.有几段完整的木棍,
2.左边是否有向右边的开口,
3.右边是否有向左边的开口,
4.以及是否完全无开口(全为'X')(便于区间合并)。
区间合并想得有点乱,但是不用下传标记的单点修改还是很exciting的。
一开始想特判一下n=1的情况来着,后来想想算了吧。
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- using namespace std;
- inline int rint(){
- char ch;
- int re=;
- bool flag=;
- while((ch=getchar())!='-'&&(ch<''||ch>''));
- ch=='-'?flag=:re=ch-'';
- while((ch=getchar())>=''&&ch<='') re=re*+ch-'';
- return flag?-re:re;
- }
- inline char rchar(){
- char ch;
- while((ch=getchar())!='X'&&ch!='('&&ch!=')');
- return ch;
- }
- struct segment{
- int l,r,num;
- bool ll,rr,xx;
- segment(){ num=; ll=; rr=; xx=; }
- };
- const int maxn=;
- segment tre[maxn<<];
- int n,m;
- segment merge(const segment &tl,const segment &tr){
- segment tx;
- tx.l=tl.l; tx.r=tr.r;
- tx.xx=tl.xx&tr.xx;
- tx.ll=tr.xx?tl.ll:tr.ll;
- tx.rr=tl.xx?tr.rr:tl.rr;
- tx.num=tl.num+tr.num+((tl.ll&tr.rr)?:);
- return tx;
- }
- void push_up(int x){
- tre[x]=merge(tre[x<<],tre[x<<|]);
- }
- void build(int x,int l,int r){
- tre[x].l=l; tre[x].r=r;
- if(l==r){
- if(l==) tre[x].ll=;
- else if(r==n) tre[x].rr=;
- else tre[x].xx=;
- return;
- }
- int mid=(l+r)>>;
- build(x<<,l,mid); build(x<<|,mid+,r);
- push_up(x);
- }
- void change(int x,int pos,int chaa){
- if(tre[x].l==tre[x].r){
- if(chaa==){
- tre[x].ll=;
- tre[x].rr=;
- tre[x].xx=;
- }
- else if(chaa==){
- tre[x].ll=;
- tre[x].rr=;
- tre[x].xx=;
- }
- else{
- tre[x].ll=;
- tre[x].rr=;
- tre[x].xx=;
- }
- return;
- }
- int mid=(tre[x].l+tre[x].r)>>;
- if(pos<=mid) change(x<<,pos,chaa);
- else change(x<<|,pos,chaa);
- push_up(x);
- }
- segment query(int x,int L,int R){
- if(L<=tre[x].l&&tre[x].r<=R) return tre[x];
- int mid=(tre[x].l+tre[x].r)>>;
- if(R<=mid) return query(x<<,L,R);
- if(L>mid) return query(x<<|,L,R);
- return merge(query(x<<,L,mid),query(x<<|,mid+,R));
- }
- int main(){
- //freopen("temp.in","r",stdin);
- n=rint(); m=rint();
- build(,,n);
- int opt,pos,left,right,chaa;
- char cha;
- for(int i=;i<m;i++){
- opt=rint();
- switch(opt){
- case :{
- pos=rint(); cha=rchar();
- if(cha=='X') chaa=;
- else if(cha=='(') chaa=;
- else chaa=;
- change(,pos,chaa);
- break;
- }
- case :{
- left=rint(); right=rint();
- printf("%d\n",query(,left,right).num);
- break;
- }
- }
- }
- return ;
- }
[luogu P3797] 妖梦斩木棒 [线段树]的更多相关文章
- Luogu P3797 妖梦斩木棒
解题思路 用线段树做这个就不用说了吧,但是要维护的东西确实很神奇.在每一个节点上都维护一个$lbkt$,表示这个区间上最靠左的右括号的位置:一个$rbkt$,表示这个区间上最靠右的左括号的位置.还有一 ...
- 洛谷 P3797 妖梦斩木棒 解题报告
P3797 妖梦斩木棒 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的\(n\)段.现在这个木棒可以看做 ...
- 洛谷P3797 妖梦斩木棒
P3797 妖梦斩木棒 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看 ...
- 洛谷 P3797 妖梦斩木棒
https://www.luogu.org/problem/show?pid=3797 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了 ...
- AC日记——妖梦斩木棒 洛谷 P3797
妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define m ...
- luogu P3799 妖梦拼木棒
二次联通门 : luogu P3799 妖梦拼木棒 /* luogu P3799 妖梦拼木棒 用一个桶存下所有的木棒 美剧两根短的木棒长度 后随便乘一乘就 好了.. */ #include <a ...
- [Luogu3797] 妖梦斩木棒
题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...
- luogu 4927 [1007]梦美与线段树 概率与期望 + 线段树
考场上切了不考虑没有逆元的情况(出题人真良心). 把概率都乘到一起后发现求的就是线段树上每个节点保存的权值和的平方的和. 这个的修改和查询都可以通过打标记来实现. 考场代码: #include < ...
- 洛谷P3799 妖梦拼木棒
P3799 妖梦拼木棒 53通过 345提交 题目提供者orangebird 标签 难度普及/提高- 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 暂时没有讨论 题目背景 上道 ...
随机推荐
- 《物联网框架ServerSuperIO教程》-20.网络通讯控制器分组,提高交互的负载平衡能力。v3.6.6 版本发布
20.1 概述 ServerSuperIO原来在网络通讯模式下,只有一个网络控制器,在自控模式.并发模式和单例模式下时都是异步处理返回的数据,并不会出现性能问题.但是在轮询模式下,一个网络控制 ...
- 高CPU、数据库无法读写的真凶
有兴趣的同学可以参考如下系列文章,都是针对dump分析的实战和总结: Windbg DUMP分析(原创汇总) http://www.cnblogs.com/LoveOfPrince/p/6653341 ...
- 安装npm及cnpm(Windows)
[工具官网] Node.js : http://nodejs.cn/ 淘宝NPM: https://npm.taobao.org/ [安装步骤] 一.安装node.js 1.前往node.js官网下载 ...
- C# 调用cmd.exe的方法
网上有很多用C#调用cmd的方法,大致如下: [c-sharp] view plaincopy private void ExecuteCmd(string command) { Proces ...
- 学习maven的各种问题
1. The container 'Maven Dependencies' references non existing library 解决方法,将eclipse中maven插件中“resolve ...
- php面试问题
问题:请用最简单的语言告诉我PHP是什么? 回答:PHP全称:Hypertext Preprocessor,是一种用来开发动态网站的服务器脚本语言. 问题:什么是MVC? 回答:MVC由Model(模 ...
- oracle表空间自增长
方式一:通过修改oracle database control 修改 第一步,点击开始--所有程序--Oracle - OraDb11g_home1--Database Control 第二步,通过g ...
- MongoDB--架构搭建(主从、副本集)之主从
此章节讲述主从架构 主从架构 -- 目前已经不建议使用,推荐使用复制集 主从配置可以在配置文件中配置 从节点可以在启动之后使用命令追加主节点,db.source.insert({"host ...
- Redis中的基本数据结构
Redis基础数据结构 基础数据结构 sds简单动态字符串 数据结构 typedef struct sdstr{ int len // 字符串分配的字节 int free // 未使用的字节数 cha ...
- IE11中navigator.userAgent的变化
在原来判断浏览器是否是ie时,我们可以根据navigator.userAgent中时候有MSIE,但是IE11进行变革,userAgent中不在包含MSIE字段, 在实际项目中,入到类似的在控制台报错 ...