zoukankan      html  css  js  c++  java
  • [思维][RMQ] G Parenthesis

    给一合法括号序列,交换xy位置的括号问交换后是否合法


    解题思路:左扩1右扩-1做前缀和数组

    当且仅到pre[i] >= 0 && pre[n] == 0时合法

    考虑交换, 若s[x] == s[y]交换无意义

    当前为'('后为')'则xy区间内差分值均要减二 所以区间极小值小于2则非法

    当前为')'后为'('交换后发现差分值只会变大,且原序列合法,则必然合法

    RMQ维护区间极值查询即可

    /*
        Zeolim - An AC a day keeps the bug away
    */
      
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x, y) memset(x, y, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f;
    const ll MOD = 386910137;
    const ull P = 13331;
    const int MAXN = 1e5 + 10;
     
    char s[MAXN];
    int fst[MAXN] = {INF};
    int lst[MAXN];
     
    struct rmq
    {
        int rmq[30][MAXN];
         
        void init(int *arr, int n)
        {
            for(int i = 0; i < n; ++i)
                rmq[0][i] = arr[i];
             
            int len = log2(n) + 1;
            for(int i = 1; i < len; ++i)
                for(int j = 0; j <= n - (1 << i) + 1; ++j)
                    rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1) )]);
        }
         
        int ask(int fst, int lst)
        {
            int k = log2(lst - fst + 1);
            return min(rmq[k][fst], rmq[k][lst - (1 << k) + 1]);
        }
    }Q;
     
    int main()
    { 
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        //freopen("d:out.txt","w",stdout);
        //freopen("d:in.txt","r",stdin);
        
        int n, m;
         
        while( cin >> n >> m )
        {
            cin >> s + 1;
             
            fill(fst, fst + n + 10, 0);
             
            for(int i = 1; i <= n; ++i)
                fst[i] = fst[i - 1] + (s[i] == '(' ? 1 : -1);
         
            fst[0] = INF; fst[n + 1] = INF;
             
            Q.init(fst, n + 1);
             
            while(m--)
            {
                int x, y;
                cin >> x >> y;
                 
                if(x > y)
                    swap(x, y);
                     
                if(s[x] == s[y])
                    cout << "Yes
    ";
                else
                {
                    bool flag = 1;
                    if(s[x] == '(')
                    {
                        if(Q.ask(x, y - 1) < 2)
                            flag = 0;
                    }
                     
                    if(flag)
                        cout << "Yes
    ";
                    else
                        cout << "No
    ";
                }
            }
        }
     
         
         
         
        return 0;
    }
  • 相关阅读:
    微信小程序设置控件权重
    从外部浏览开启app
    对rxandroid的简单理解
    react native TextInput
    使用广播来进行刷新页面
    react native中对props和state的理解
    android中四大组件之间相互通信
    android tab选项卡的使用
    android控件 ToggleButton的应用
    Listview的使用
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270335.html
Copyright © 2011-2022 走看看