• CSU


    CSU - 1542
    Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld & %llu

     Status

    Description

    Input

     

    Output

     

    Sample Input

    6 3
    ((()))
    4
    3
    1

    Sample Output

    2
    2
    1

    Hint

     

    题意:先给出一个符合括号匹配的字符串。然后Q次操作

    每次操作将某个括号反转,问将哪个括号反转能使字符串的括号再次匹配,位置要取最左端符合条件的。

    能够利用前缀和 比方(())那么前缀和分别就是1,2,1,0。观察到。平衡时前缀和都是等于0的。


    通过前缀和,我们能够发现规律:

    将一个'('翻转成')'会使得从当前位置開始到字符串最后的前缀和都会减2

    假设将')'翻转成'(',同理,此位置開始以后的全部前缀和都要加2

    而假设减去了2,那怎样添加2抵消掉之前的影响,得到最后的后缀和为零

    而减去2的话肯定是'('翻转成')'。那么怎样加一个数抵消掉')'的影响

    假设是将p点翻转的话,肯定是从[1,p],找一个')',将')'翻转成'('

    有没有发现规律,假设是'('翻转成')',则是在之前的区间将')'翻转成'('。那么将')'翻转成'('时,就是往后,找一个'('将其'('翻转成')'

    维护该区间的最小值就可以。仅仅要最小值不小于2,那么该区间的全部值都不会小于2

    提供一个朋友的具体解释地址,说的非常好:http://blog.csdn.net/qwb492859377/article/details/47357553

    /*
    Author: 2486
    Memory: 32700 KB		Time: 760 MS
    Language: C++		Result: Accepted
    VJ RunId: 4340427		Real RunId: 149963
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    
    using namespace std;
    #define lson rt << 1, l, mid
    #define rson rt << 1|1, mid + 1, r
    #define root 1, 1, n
    const int MAXN = 5e5 + 5;
    const int INF = 0x3f3f3f3f;
    
    int sum[MAXN << 2];
    int Min[MAXN << 2],col[MAXN << 2],val[MAXN << 2];
    int S,n,m;
    char str[MAXN];
    
    void pushup_1(int rt) {
        sum[rt] = min(sum[rt << 1], sum[rt << 1|1]);
    }
    
    void build(int rt, int l, int r) {
        col[rt] = 0;
        if(l == r) {
            val[rt] = (str[l] == '(' ? 1 : -1);
            S += val[rt];
            Min[rt] = S;
            sum[rt] = val[rt] == 1 ?

    INF : l; return; } int mid = (l + r) >> 1; build(lson); build(rson); pushup_1(rt); Min[rt] = min(Min[rt << 1], Min[rt << 1|1]); } int update_1(int p, int rt, int l, int r) { if(l == r) { int tmp = val[rt]; val[rt] *= -1; sum[rt] = tmp == 1 ?

    p : INF; return tmp; } int mid = (l + r) >> 1, ret; if(p <= mid) ret = update_1(p, lson); if(p > mid) ret = update_1(p, rson); pushup_1(rt); return ret; } void pushdown(int rt) { if(col[rt]) { col[rt << 1] += col[rt]; col[rt << 1|1] += col[rt]; col[rt] = 0; } } void pushup_2(int rt) { Min[rt] = min(Min[rt << 1] + col[rt << 1], Min[rt << 1|1] + col[rt << 1|1]); } void update_2(int L, int R, int c,int rt, int l, int r) { if(L <= l && r <= R) { col[rt] += c; return; } pushdown(rt); int mid = (l + r) >> 1; if(L <= mid) update_2(L, R, c, lson); if(R > mid) update_2(L, R, c, rson); pushup_2(rt); } int query(int rt, int l,int r) { if(Min[rt] + col[rt] >= 2) return l; if(l == r) return r + 1; pushdown(rt); int mid = (l + r) >> 1; int ret; if(Min[rt << 1|1] + col[rt << 1|1] >= 2) ret = query(lson); else ret = query(rson); pushup_2(rt); return ret; } int main() { int p; while(~scanf("%d %d",&n,&m)) { scanf("%s",str+1); S = 0; build(root); while(m--) { scanf("%d",&p); int tmp = update_1(p, root); update_2(p, n, tmp * (-2), root); printf("%d ",p = (tmp == 1 ?

    sum[1] : query(root))); update_1(p, root); update_2(p, n, tmp * 2, root); } } return 0; }



  • 相关阅读:
    nyoj 599-奋斗的小蜗牛 (double ceil(); (temp
    nyoj 596-谁是最好的Coder (greater, less)
    nyoj 517-最小公倍数 (python range(start, end) range(length))
    用深度学习预测专业棋手走法
    阿里AI设计师一秒出图,小撒连连惊呼,真相是...
    想成为数据科学家?先做到这6点吧!
    Kubernetes 弹性伸缩全场景解析 (一)- 概念延伸与组件布局
    机器学习基础:(Python)训练集测试集分割与交叉验证
    Data Lake Analytics + OSS数据文件格式处理大全
    聊聊Flexbox布局中的flex的演算法
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6785854.html
Copyright © 2020-2023  润新知