zoukankan      html  css  js  c++  java
  • 洛谷 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,输出一行一个整数,表示对应询问的答案。

    输入输出样例

    输入样例#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

    由于只有当两个括号之间没有其他括号时 才能构成一个完整的木棒

    所以合并区间的时候只有 左区间最右端的左括号和右区间最左端的右括号 匹配才能对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
    ",ans.sum);
    87         }
    88     }
    89     return 0;
    90 } 
    91 
    92 int sb=hh();
    93 int main(int argc,char**argv) {;}
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    这鸡汤、真香
    linux 编译安装python并且安装虚拟环境工具
    前端数据删除
    前后端分离DRF项目初始化
    ubuntu 安装nginx docker
    ubuntu安装vue
    虚拟环境安装
    sql语句优化
    Python之网络编程 进程 线程 协程
    Python之网络编程 文件上传 基于udp的协议的socket socketsever同时接收多方消息
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7486137.html
Copyright © 2011-2022 走看看