zoukankan      html  css  js  c++  java
  • [Luogu3797] 妖梦斩木棒

    题目背景

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

    题目描述

    有一天,妖梦正在练习剑术。地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的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


    调了3个小时无果。

    弃疗了。

    留下代码以后调。


    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    using namespace std;
    #define reg register 
    inline int read() {
        int res = 0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
        return res;
    }
    #define N 200005
    int n, m;
    
    int L1[N<<2], R1[N<<2], dat[N<<2], L2[N<<2], R2[N<<2];
    #define ls(o) o << 1 
    #define rs(o) o << 1 | 1 
    
    inline void pushup(int o)
    {
        dat[o] = dat[ls(o)] + dat[rs(o)];
        if (L2[ls(o)] > R1[ls(o)] and R2[rs(o)] < L1[rs(o)]) dat[o]++;    
        L1[o] = min(L1[ls(o)], L1[rs(o)]);
        L2[o] = max(L2[ls(o)], L2[rs(o)]);
        R1[o] = max(R1[ls(o)], R1[rs(o)]);
        R2[o] = min(R2[ls(o)], R2[rs(o)]);
    }
    
    void Build(int l, int r, int o)
    {
        if (l == r) {
            if (l == 1) L1[o] = 1, L2[o] = 1, R1[o] = 0, R2[o] = 1e9;
            else if (l == n) R1[o] = n, L1[o] = 1e9, L2[o] = 0, R2[o] = n;
            else L1[o] = 1e9, L2[o] = 0, R1[o] = 0, R2[o] = 1e9;
            return ;
        }
        int mid = l + r >> 1;
        Build(l, mid, ls(o));
        Build(mid + 1, r, rs(o));
        pushup(o);
    }
    
    void change(int l, int r, int o, int pos, char c)
    {
        if (l == r) 
        {
            if (c == '(') L1[o] = pos, L2[o] = pos, R1[o] = 0, R2[o] = 1e9;
            else if (c = ')') R1[o] = pos, R2[o] = pos, L1[o] = 1e9, L2[o] = 0;
            else L1[o] = 1e9, L2[o] = 0, R1[o] = 0, R2[o] = 1e9;
            return ;
        }
        int mid = l + r >> 1;
        if (pos <= mid) change(l, mid, ls(o), pos, c);
        else change(mid + 1, r, rs(o), pos, c);
        pushup(o);
    }
    
    int query(int l, int r, int o, int ql, int qr)
    {
        if (l >= ql and r <= qr) return dat[o];
        int res = 0;
        int mid = l + r >> 1;
        if (ql <= mid) res += query(l, mid, ls(o), ql, qr);
        if (qr > mid) res += query(mid + 1, r, rs(o), ql, qr);
        if (ql <= mid and qr > mid and L2[ls(o)] > R1[ls(o)] and R2[rs(o)] < L1[rs(o)] and L2[ls(o)] >= ql and R2[rs(o)] <= qr) res++;
        return res;
    }
    
    int main()
    {
        //freopen("testdatain.txt", "r", stdin);
        //freopen("ym.ans", "w", stdout); 
        n = read(), m = read();
        Build(1, n, 1);
        while(m--)
        {
            int opt = read();
            if (opt == 1) {
                int x = read();
                char y;
                cin >> y;
                change(1, n, 1, x, y);
            } else {
                int x = read(), y = read();
                printf("%d
    ", query(1, n, 1, x, y));
            }
        }
        return 0;
    }
  • 相关阅读:
    MacOS Mojave启动U盘制作及安装方法详细介绍
    Boostnote for Mac——如何使用TeX精美地编写数学公式
    pycharm pro 2019 mac如何重构?
    Understand教程—使用搜索功能的几种方法
    Understand Mac项目视图初级使用
    文本代码编辑CudaText for Mac使用方法
    java学习笔记之面向对象接口
    java学习笔记之遍历ArrayList的三种方法
    java学习笔记之面向对象static,final关键字
    java学习笔记之eclipse下jar包导入
  • 原文地址:https://www.cnblogs.com/BriMon/p/9610436.html
Copyright © 2011-2022 走看看