[思維][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\n";
            else
            {
                bool flag = 1;
                if(s[x] == '(')
                {
                    if(Q.ask(x, y - 1) < 2)
                        flag = 0;
                }
                 
                if(flag)
                    cout << "Yes\n";
                else
                    cout << "No\n";
            }
        }
    }
 
     
     
     
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章