• 2018湖南多校第五场-20180506 训练日志


    solved 5 (a b d f g)

    rank 5/28

    总体发挥较佳,虽然中期卡在了D,最后成绩还是完成了flag。dzcjj太强辣。

    最直观的感受就是觉得时间不够用,这比之前做完水题就挂机的水平还是有很强的提高的。

    Bit String Reordering(暴搜)

    Miscalculation(模拟)

    <qj>

    本场最水的一道题,完全码力题。

    题意:给一个字符串,里面包含了一些数学运算的式子,求两种定义下的值。(只存在加法和乘法)

    第一种定义:先乘除后加减。

    第二种定义:从左至右运算。

    解法:模拟一下便可。(第一种可以用到stack来解决,第二种可以直接搞,当然也可以用queue)

    Space Golf(推物理公式)

    There is No Alternative(最小生成树相关)

    Flipping Parentheses (线段树 + 二分)

    <qj>

    题意:

    给一个初始的字符串,由左括号和右括号组成,保证初始字符串平衡。

    q个查询,翻转第pos个括号,问你翻转哪一个最靠左的括号能够使序列重新平衡。

    每次操作会影响到后面的操作。

    思路:

    遇到括号平衡的问题,我们一般会想到前缀和表达,但这个题里存在翻转(修改)的操作,那么不难想到,能够实现前缀和 + 修改 的数据结构有线段树或树状数组。

    由于性质,最后一个括号一定是 ‘)’ ,且prefix(最后一个)值为0, 才会平衡。

    1.

    如果翻转了一个 ')',那么从pos开始到结尾的前缀和应该都 +2 ,我们可以用线段树把这个区间的值都 +2 。

    已知串要平衡,最后一个位置前缀和应该是 0 ,而目前最后一个位置是 2。

    那么我们需要找到一个pos2,pos2翻转,使得[pos2,n]区间 -2。

    然后这里为了不破坏平衡,区间内所有值都必须大于等于2。所以线段树可以去维护一个区间最小值,若区间最小值不小于2,该区间满足条件。

    怎么找到最左的pos呢,我们可以用到二分搜索。

    int l = 0, r = n+1;int mid  = l+r>>1;

    如果mid往右的所有前缀和满足条件,那么我们往左找[l,mid],否则往右找[mid,n]。

    复杂度 O(Q*logN*logN)

    2.

    如果翻转了‘(’ , 跟上面是类似的。最后一个位置的前缀和应该是 -2。

    如何找到最左的一个括号翻转,并使得最后一个位置前缀和变成0呢?

    翻转从左开始第一个‘)’便可。

    若前面全是'('不难知道,在第pos个位置,prefix(pos)==pos,说明前面没有出现过')' 。

    同上,二分去找第一个prefix(pos)!=pos的位置就可以了。

    复杂度 O(Q*logN*logN)

    上代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define maxn 300055
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define intmid  int mid = (l+r)>>1
    int n,q;
    char s[maxn];
    int pre[maxn];
    int cur[maxn<<2],minv[maxn<<2];
    void push_up(int rt){
        minv[rt] = min(minv[rt<<1] , minv[rt<<1|1]);
    }
    
    void push_down(int l,int r,int rt){
        if(cur[rt]){
            intmid;
            cur[rt<<1]  += cur[rt];
            cur[rt<<1|1]+= cur[rt];
            minv[rt<<1]  += cur[rt];
            minv[rt<<1|1]+= cur[rt];
            cur[rt]=0;
        }
    }
    
    void build(int l,int r,int rt){
        intmid;
        cur[rt]=0;
        if(l==r){
            minv[rt]=pre[l];
            return ;
        }
        push_down(l,r,rt);
        build(lson);build(rson);
        push_up(rt);
    }
    
    void update(int ll,int rr,int val,int l,int r,int rt){
        intmid;
        if( ll<=l && rr>=r ){
            cur[rt]+=val;
            minv[rt]+=val;
            return ;
        }
        push_down(l,r,rt);
        if(ll<=mid)update(ll,rr,val,lson);
        if(rr>mid)update(ll,rr,val,rson);
        push_up(rt);
    }
    
    int querymin(int ll,int rr,int l,int r,int rt){
        int ret=0x3f3f3f3f;
        if(ll<=l && rr>=r){
            return minv[rt];
        }
        push_down(l,r,rt);
        intmid;
        if(ll<=mid) ret = min(ret,querymin(ll,rr,lson));
        if(rr>mid) ret = min(ret,querymin(ll,rr,rson));
        return ret;
    }
    
    bool check(int pos){
        int v = querymin(pos,n,1,n,1);
        if(v<2)return 1;
        return 0;
    }
    
    bool check2(int pos){
        int v = querymin(pos,pos,1,n,1);
        if(v==pos)return 1;
        return 0;
    }
    
    int main(){
        while(scanf("%d%d",&n,&q)!=EOF){
            scanf("%s",s+1);
            for(int i=1;i<=n;i++){
                pre[i]=pre[i-1];
                if(s[i]=='(')pre[i]++;
                else pre[i]--;
            }
            build(1,n,1);
            while(q--){
                int pos;
                scanf("%d",&pos);
                if(s[pos]=='('){
                    s[pos]=')';
                    update(pos,n,-2,1,n,1);
                    int l=0,r=n+1;
                    while(l<r-1){
                        intmid;
                        if(check2(mid)){
                            l=mid;
                        }
                        else r=mid;
                    }
                    printf("%d
    ",r);
                    s[r]='(';
                    update(r,n,2,1,n,1);
    
                } else{
                    s[pos]='(';
                    update(pos,n,2,1,n,1);
                    int l=0,r=n+1;
                    while(l<r-1){
                        intmid;
                        if(check(mid)){
                            l=mid;
                        }
                        else r=mid;
                    }
                    printf("%d
    ",r);
                    s[r]=')';
                    update(r,n,-2,1,n,1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    [原创]PostgreSQL Plus Advanced Server批量创建分区表写入亿级别数据实例
    [原创]从Oracle和Microsoft Sql Server迁移到PostgreSQL Plus Advanced Server
    [原创]PostgreSQL Plus Advince Server在 HA环境中一对多的Stream Replication配置(四)
    【译】x86程序员手册41-10.6 TLB(快表)测试
    【译】x86程序员手册40-10.5初始化的例子
    【译】x86程序员手册39-10.3切换到保护模式
    【译】x86程序员手册38-10.2实在址模式下的软件初始化
    【译】x86程序员手册37-第10章 初始化
    【译】x86程序员手册36-9.9异常汇总
    【译】x86程序员手册35-9.8异常条件
  • 原文地址:https://www.cnblogs.com/dowhile0/p/9001735.html
Copyright © 2020-2023  润新知