题目背景

妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力。

题目描述

有一天,妖梦正在练习剑术。地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的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,输出一行一个整数,表示对应询问的答案。

输入输出样例

输入样例#1:

4 4
2 1 4
2 2 4
1 2 (
2 2 4
输出样例#1:

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] 妖梦斩木棒 [线段树]的更多相关文章

  1. Luogu P3797 妖梦斩木棒

    解题思路 用线段树做这个就不用说了吧,但是要维护的东西确实很神奇.在每一个节点上都维护一个$lbkt$,表示这个区间上最靠左的右括号的位置:一个$rbkt$,表示这个区间上最靠右的左括号的位置.还有一 ...

  2. 洛谷 P3797 妖梦斩木棒 解题报告

    P3797 妖梦斩木棒 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的\(n\)段.现在这个木棒可以看做 ...

  3. 洛谷P3797 妖梦斩木棒

    P3797 妖梦斩木棒 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看 ...

  4. 洛谷 P3797 妖梦斩木棒

    https://www.luogu.org/problem/show?pid=3797 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了 ...

  5. AC日记——妖梦斩木棒 洛谷 P3797

    妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define m ...

  6. luogu P3799 妖梦拼木棒

    二次联通门 : luogu P3799 妖梦拼木棒 /* luogu P3799 妖梦拼木棒 用一个桶存下所有的木棒 美剧两根短的木棒长度 后随便乘一乘就 好了.. */ #include <a ...

  7. [Luogu3797] 妖梦斩木棒

    题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...

  8. luogu 4927 [1007]梦美与线段树 概率与期望 + 线段树

    考场上切了不考虑没有逆元的情况(出题人真良心). 把概率都乘到一起后发现求的就是线段树上每个节点保存的权值和的平方的和. 这个的修改和查询都可以通过打标记来实现. 考场代码: #include < ...

  9. 洛谷P3799 妖梦拼木棒

    P3799 妖梦拼木棒 53通过 345提交 题目提供者orangebird 标签 难度普及/提高- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 暂时没有讨论 题目背景 上道 ...

随机推荐

  1. Centos 环境一键部署脚本(shell脚本)

    谨以此文纪念吊炸天的Centos环境一键部署方案的新鲜出炉 辛苦大半年,产品准备上线了,BOSS亲自体验安装部署,看着超过200+页的安装文档直接崩溃了(需要部署23个基础服务),经历了超过3个小时的 ...

  2. Spring事务管理—aop:pointcut expression解析

    先来看看这个spring的配置文件的配置: <!-- 事务管理器 --> <bean id="transactionManager"  class="o ...

  3. AngularJS高级程序设计读书笔记 -- 指令篇 之 内置指令

    1. 内置指令(10-12 章) AngularJS 内置超过 50 个内置指令, 包括 数据绑定,表单验证,模板生成,时间处理 和 HTML 操作. 指令暴露了 AngularJS 的核心功能, 如 ...

  4. redis 对象

    redis通过前面几篇的数据结构构键了一个对象系统,这个对象系统包含了字符串对象,列表对象,哈希对象,集合对象,有序集合对象 每一个对象都是一个redisobject typedef struct r ...

  5. oracle表空间增长异常或表空间占用过高问题分析

    本人对oracle调优还处在不断学习状态,这个问题是之前处理的项目上遇到过的,顺利解决了,分享下此类问题的处理思路,不足之处,还请指正. 项目上反馈说业务表空间增长越来越快,上次新增的30G数据文件, ...

  6. tcpdf导出pdf数据支持中文的解决方案

    步骤如下:1.确保你测试tcpdf能正常输出英文内容的pdf2.测试输入中文内容后显示是?的乱码或者空白分析原因,是因为我们输入的中文,tcpdf字体库并不支持,因此乱码或者空白显示 添加一个合适的字 ...

  7. 微信支付之统一下单--JAVA版

    都说微信支付有些坑,都抱怨微信支付的文档太烂,一会APPId,一会商户id,还有appsecret,支付API秘钥让你傻傻分不清楚,还有这里大写那里小写,几种标准,让你眼花缭乱.没错,这就是很多技术团 ...

  8. django-xadmin中APScheduler的启动初始化

    环境: python3.5.x + django1.9.x +  xadmin-for-python3 APScheduler做为一个轻量级和使用量很多的后台任务计划(scheduler)包,可以方便 ...

  9. 【Android Developers Training】 80. 管理网络使用

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  10. 11.page,pagcontext,config对象