洛谷 P3797 妖梦斩木棒
来源:互联网 发布:华润网络 百度国际大厦 编辑:程序博客网 时间:2024/05/22 11:57
题目描述
有一天,妖梦正在练习剑术。地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的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 42 1 42 2 41 2 (2 2 4
101
说明
对于30%的数据,1<=n,m<=1000
对于100%的数据,1<=n,m<=200000
by-orangebird
由于只有当两个括号之间没有其他括号时 才能构成一个完整的木棒
所以合并区间的时候只有 左区间最右端的左括号和右区间最左端的右括号 匹配才能对sum产生1的贡献
所以对于一个区间我们只需要为维护 三个域
le 区间最左端的非X木棒
ri 区间最右端的非X木棒
sum 区间合法木棒和
1 #include <cctype> 2 #include <cstdio> 3 4 const int MAXN=200010; 5 6 int n,m; 7 8 struct SegmentTree { 9 int l,r;10 int le,ri;11 int sum;12 };13 SegmentTree t[MAXN<<2];14 15 inline void read(int&x) {16 int f=1;register char c=getchar();17 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());18 for(;isdigit(c);x=x*10+c-48,c=getchar());19 x=x*f;20 }21 22 inline void up(int now) {23 if(t[now<<1].le) t[now].le=t[now<<1].le;else t[now].le=t[now<<1|1].le;24 if(t[now<<1|1].ri) t[now].ri=t[now<<1|1].ri;else t[now].ri=t[now<<1].ri;25 t[now].sum=t[now<<1].sum+t[now<<1|1].sum;26 if(t[now<<1].ri==1&&t[now<<1|1].le==2) ++t[now].sum;27 }28 29 void build_tree(int now,int l,int r) {30 t[now].l=l;t[now].r=r;31 if(l==r) {32 if(l==1) t[now].le=t[now].ri=1;33 else if(l==n) t[now].le=t[now].ri=2;34 return;35 }36 int mid=(l+r)>>1;37 build_tree(now<<1,l,mid);38 build_tree(now<<1|1,mid+1,r);39 up(now);40 }41 42 void modify(int now,int pos,char s) {43 if(t[now].l==t[now].r) {44 if(s=='(') t[now].le=t[now].ri=1;45 else if(s==')') t[now].le=t[now].ri=2;46 else t[now].le=t[now].ri=0;47 t[now].sum=0;48 return;49 }50 int mid=(t[now].l+t[now].r)>>1;51 if(pos<=mid) modify(now<<1,pos,s);52 else modify(now<<1|1,pos,s);53 up(now);54 }55 56 SegmentTree query(int now,int l,int r) {57 if(l<=t[now].l&&r>=t[now].r) return t[now];58 int mid=(t[now].l+t[now].r)>>1;59 if(r<=mid) return query(now<<1,l,r);60 if(l>mid) return query(now<<1|1,l,r);61 else {62 SegmentTree a,b,c;63 a=query(now<<1,l,mid);b=query(now<<1|1,mid+1,r);64 if(a.le) c.le=a.le;else c.le=b.le;65 if(b.ri) c.ri=b.ri;else c.ri=a.ri;66 c.sum=a.sum+b.sum;67 if(a.ri==1&&b.le==2) ++c.sum;68 return c;69 }70 }71 72 int hh() {73 int type,x,y;74 char c[5];75 read(n);read(m);76 build_tree(1,1,n);77 for(int i=1;i<=m;++i) {78 read(type);read(x);79 if(type==1) {80 scanf("%s",c);81 modify(1,x,c[0]);82 }83 else {84 read(y);85 SegmentTree ans=query(1,x,y);86 printf("%d\n",ans.sum);87 }88 }89 return 0;90 } 91 92 int sb=hh();93 int main(int argc,char**argv) {;}
- 洛谷 P3797 妖梦斩木棒
- 洛谷 红魔馆OI 妖梦斩木棒
- 洛谷 P2383 狗哥玩木棒
- 洛谷P3799 妖梦拼木棒
- 木棒
- 木棒
- 木棒
- 木棒
- 洛谷 红魔馆OI 妖梦拼木棒 [组合数学]
- 木棒问题
- 木棒三角形
- poj_1011木棒
- poj1011木棒
- poj 木棒
- 木棒三角形
- 【poj1011】木棒
- POJ1011 木棒
- POJ1011 木棒
- 自定义MongoDB连接池
- P3014 [USACO11FEB]牛线Cow Line
- 2017-10-15离线赛总结
- 洛谷 U3357 C2-走楼梯
- 1821: [JSOI2010]Group 部落划分 Group
- 洛谷 P3797 妖梦斩木棒
- 1093: [ZJOI2007]最大半连通子图
- QueryDSL的DEMO示例
- 1266: [AHOI2006]上学路线route
- 栈和 队列 和 优先队列的 简单操作(初学者)
- [USACO09DEC]牛收费路径Cow Toll Paths
- HTTP请求行、请求头、请求体详解
- 洛谷 P1262 间谍网络
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5