洛谷 P3797 妖梦斩木棒
https://www.luogu.org/problem/show?pid=3797
题目背景

妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力。
题目描述
有一天,妖梦正在练习剑术。地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的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
考虑了线段树,就不需要考虑形如(((XX)))怎么办
因为线段树都是由底层一步一步合并上去的
sum[k]=sum[l]+sum[r]+(左边最后是(,右边开始是))
维护完整木棒数、区间最后边是否为(,区间最前边是否为)
#include<cstdio>
#define N 200001
using namespace std;
int sum[N<<],mid[N<<],num[N<<];
int ty[N];
bool left[N<<],right[N<<];
struct node
{
int tot,tot2;
bool left,right;
node() { left=right=false; tot=tot2=;}
};
void build(int k,int l,int r)
{
if(l==r) return;
mid[k]=l+r>>;
build(k<<,l,mid[k]);
build(k<<|,mid[k]+,r);
}
void change(int k,int l,int r,int pos,int w)
{
if(l==r)
{
ty[pos]=w;
left[k]=w== ? true : false;
right[k]=w== ? true : false;
if(w) num[k]=;
else num[k]=;
return;
}
if(pos<=mid[k]) change(k<<,l,mid[k],pos,w);
else change(k<<|,mid[k]+,r,pos,w);
if(left[k<<|]) left[k]=true;
else if(!num[k<<|] && left[k<<]) left[k]=true;
else left[k]=false;
if(right[k<<]) right[k]=true;
else if(!num[k<<] && right[k<<|]) right[k]=true;
else right[k]=false;
sum[k]=sum[k<<]+sum[k<<|]+(left[k<<] & right[k<<|]);
num[k]=num[k<<]+num[k<<|];
}
node merge(node p,node q)
{
node res;
res.tot=p.tot+q.tot+(p.left & q.right);
res.tot2=p.tot2+q.tot2;
if(q.left) res.left=true;
else if(!q.tot2 && p.left) res.left=true;
else res.left=false;
if(p.right) res.right=true;
else if(!p.tot2 && q.right) res.right=true;
else res.right=false;
return res;
}
node query(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr)
{
node res;
res.left=left[k] ? true : false;
res.right=right[k] ? true : false;
res.tot=sum[k];
res.tot2=num[k];
return res;
}
if(opr<=mid[k]) return query(k<<,l,mid[k],opl,opr);
if(opl>mid[k]) return query(k<<|,mid[k]+,r,opl,opr);
return merge(query(k<<,l,mid[k],opl,opr),query(k<<|,mid[k]+,r,opl,opr));
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(,,n);
change(,,n,,);
change(,,n,n,);
int type,x,y;
char c[];
while(m--)
{
scanf("%d%d",&type,&x);
if(type==)
{
scanf("%s",c);
if(c[]=='X') y=;
else if(c[]=='(') y=;
else y=;
change(,,n,x,y);
}
else
scanf("%d",&y),printf("%d\n",query(,,n,x,y).tot);
}
}
洛谷 P3797 妖梦斩木棒的更多相关文章
- 洛谷 P3797 妖梦斩木棒 解题报告
P3797 妖梦斩木棒 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的\(n\)段.现在这个木棒可以看做 ...
- 洛谷P3797 妖梦斩木棒
P3797 妖梦斩木棒 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看 ...
- 洛谷P3799 妖梦拼木棒
P3799 妖梦拼木棒 53通过 345提交 题目提供者orangebird 标签 难度普及/提高- 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 暂时没有讨论 题目背景 上道 ...
- [luogu P3797] 妖梦斩木棒 [线段树]
题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...
- Luogu P3797 妖梦斩木棒
解题思路 用线段树做这个就不用说了吧,但是要维护的东西确实很神奇.在每一个节点上都维护一个$lbkt$,表示这个区间上最靠左的右括号的位置:一个$rbkt$,表示这个区间上最靠右的左括号的位置.还有一 ...
- AC日记——妖梦斩木棒 洛谷 P3797
妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define m ...
- [Luogu3797] 妖梦斩木棒
题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...
- AC日记——妖梦拼木棒 洛谷 P3799
妖梦拼木棒 思路: 神特么题: 代码: #include <bits/stdc++.h> using namespace std; #define mod 1000000007LL int ...
- P3799 妖梦拼木棒 (组合数学)
题目背景 上道题中,妖梦斩了一地的木棒,现在她想要将木棒拼起来. 题目描述 有n根木棒,现在从中选4根,想要组成一个正三角形,问有几种选法? 输入输出格式 输入格式: 第一行一个整数n 第二行n个整数 ...
随机推荐
- 几道很Interesting的偏序问题
若干道偏序问题(STL,分块) 找了4道题目 BZOJ陌上花开(权限题,提供洛谷链接) Cogs2479偏序 Cogs2580偏序II Cogs2639偏序++ 作为一个正常人,肯定先看三维偏序 做法 ...
- 【NOI2001】炮兵阵地(状态压缩,动态规划)
题面 题面中有图片的存在,所以就贴个地址把 题解 简单题,,,, 原来一直觉得不会做... 现在发现是一道傻逼题 暴力压两行的状态 发现就需要滚一维. 然后暴力检查一下状态的可行性 DP检查MAX就可 ...
- Django的models实现分析
1 引子 1.1 神奇的Django中的models 我们先来看一段在Django项目中常用的代码: 设置数据库models代码: class Students(models.Mod ...
- Adaboost的意义
Adaboost是广义上的提升方法(boosting method)的一个特例.广泛应用于人脸识别等领域. 它的基本思想是,“三个臭皮匠赛过诸葛亮”,即用多个弱分类器的线性加权,来得到一个强的分类器. ...
- 面向服务的体系架构 SOA(二) --- 服务的路由和负载均衡
2. 服务的路由和负载均衡 1.2.1 服务化的演变 SOA设计思想:分布式应用架构体系对于业务逻辑复用的需求十分强烈,上层业务都想借用已有的底层服务来快速搭建更多.更丰富的应用,降低新业务开展的人力 ...
- 洛谷 P1025 数的划分
题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输 ...
- 关于Android sdkmanager目录结构的总结
SDK Platform是指一些已经编写好的库函数,类文件,我们可以直接调用 Samples for SDK是指一些样本代码,可以导入eclipse运行出来查看里面函数的效果 以system imag ...
- Java中常见的URL问题及解决方案
URL无处不在,不过似乎开发人员并没有真正地理解它们,因为在Stack Overflow上经常看到有人在问如何正确的创建一个URL.想知道URL语法是如何工作的,可以看下兄弟连教育总结的这篇文章,非常 ...
- Java中调用文件中所有bat脚本
//调用外部脚本String fileips=null;//所有的路径String[] files=null;String fileip=null;//单个路径try { InputStream is ...
- Javscript的垃圾回收
和C#.Java一样JavaScript有自动垃圾回收机制,也就是说执行环境会负责管理代码执行过程中使用的内存,在开发过程中就无需考虑内存分配及无用内存的回收问题了.JavaScript垃圾回收的机制 ...