zoukankan      html  css  js  c++  java
  • Princess principal

    题意

    有一个(n)个括号的文档,括号由(m)种。我们定义用如下的方式定义一个合法的文档

    • 一个空字符串是一个合法的文档

    • 如果(A),(B)都是合法的文档,那么(AB)也是合法的文档

    • 如果(S)是合法的文档,那么(aSb)也是合法的文档,其中(a,b)是同一种括号

    现给出(q)个询问,问([l,r])范围内是否是合法文档。

    (1 le n, m, q le 10^6)

    方法一

    直接差分,orzzzzz。和只有一种括号的差分是一样一样的。遍历到左括号加一,遍历到匹配的右括号减一,用栈来实现保证了这样做的正确性。。。。

    代码

    const int N = 1000005;
    
    int n, m, q;
    int a[N], ans[N];
    
    stack<int> st;
    
    int main()
    {
        sc(n), sc(m), sc(q);
        Rep(i, 1, n) sc(a[i]);
    
        ans[0] = 0;
        Rep(i, 1, n) {
            if (st.empty() || (a[i] & 1) == 0) st.push(i);
            else {
                if (a[st.top()] == a[i] - 1) st.pop();
                else st.push(i);
            }
            if (st.empty()) ans[i] = 0;
            else ans[i] = st.top();
        }
    
        Rep(i, 1, q) {
            int l, r;
            sc(l), sc(r);
            puts((ans[l - 1] == ans[r] ? "Yes" : "No"));
        }
    
        return 0;
    }
    
    

    方法二

    先找出不能匹配的位置,① ([l,r])包含这些位置就直接判断;② ([l,r])是合法位置的子串:对于一个括号,它如果能合法匹配,就记录它匹配的括号的位置。然后查询([l,r])范围内括号的匹配位置pos是否存在(pos < l)或者(pos > r)

    代码

    const int N = 1000005;
    
    int n, m, q, tot;
    int use[N], sum[N], le[N], re[N], Min[4 * N], Max[4 * N];
    
    P p[N];
    
    void Pushup(int root) {
        Min[root] = min(Min[lson], Min[rson]);
        Max[root] = max(Max[lson], Max[rson]);
    }
    
    void Build(int l, int r, int root) {
        if (l == r) {
            tot++;
            Min[root] = le[tot];
            Max[root] = re[tot];
            return;
        }
        int mid = (l + r) >> 1;
        Build(l, mid, lson);
        Build(mid + 1, r, rson);
        Pushup(root);
    }
    
    int QueryMin(int l, int r, int root, int L, int R) {
        if (l > R || r < L) return INF32;
        if (L <= l && r <= R) return Min[root];
        int mid = (l + r) >> 1;
        int ans = INF32;
        ans = min(ans, QueryMin(l, mid, lson, L, R));
        ans = min(ans, QueryMin(mid + 1, r, rson, L, R));
        return ans;
    }
    
    int QueryMax(int l, int r, int root, int L, int R) {
        if (l > R || r < L) return 0;
        if (L <= l && r <= R) return Max[root];
        int mid = (l + r) >> 1;
        int ans = 0;
        ans = max(ans, QueryMax(l, mid, lson, L, R));
        ans = max(ans, QueryMax(mid + 1, r, rson, L, R));
        return ans;
    }
    
    int main()
    {
        sc(n), sc(m), sc(q);
        Rep(i, 1, n) {
            le[i] = INF32;
            re[i] = 0;
    
            sc(p[i].first);
            p[i].first = ((p[i].first & 1) ? p[i].first / 2 + m : p[i].first / 2);
            p[i].second = i;
        }
        stack<P> st;
        Rep(i, 1, n) {
            if (st.empty()) st.push(p[i]);
            else {
                if (p[i].first >= m) {
                    P tp = st.top();
                    st.pop();
                    if (tp.first != p[i].first - m) {
                        st.push(p[i]);
                        st.push(tp);
                    }
                    else {
                        re[tp.second] = p[i].second;
                        le[p[i].second] = tp.second;
                    }
                }
                else {
                    st.push(p[i]);
                }
            }
        }
        while(!st.empty()) {
            P tp = st.top();
            st.pop();
            use[tp.second] = 1;
        }
    
        Rep(i, 1, n) sum[i] = sum[i - 1] + use[i];
        
        Build(1, n, 1);
    
        while(q--) {
            int l, r;
            sc(l), sc(r);
    
            if (use[l] || (sum[l] != sum[r]) || QueryMax(1, n, 1, l, r) > r || QueryMin(1, n, 1, l, r) < l) puts("No");
            else puts("Yes");
        }
    
        return 0;
    }
    
  • 相关阅读:
    常用的dos命令
    定时器
    自动化工具下载地址
    Eclipse自动提示
    An error occurred: No action handlers found
    生产消费的经典案例
    SpringBoot 优雅的参数效验
    40 个 SpringBoot 常用注解
    极简入门,Shiro的认证与授权流程解析
    Java多线程批量处理、线程池的使用
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9735704.html
Copyright © 2011-2022 走看看