2018 Hunan Multi-School Game 5-20180506 Training Log

solved 5 (a b d f g)

rank 5/28

 

The overall performance is better. Although it was stuck at D in the mid-term, the final result still completed the flag. dzcjj is too strong and spicy.

The most intuitive feeling is that there is not enough time, which is a strong improvement compared to the previous level of hanging up after finishing the water problem.

 

Bit String Reordering(暴搜)

 

Miscalculation (simulation)

<qj>

The most watery question in this field is a complete code question.

The meaning of the question: Given a string containing some mathematical expressions, find the values ​​under the two definitions. (only addition and multiplication exist)

The first definition: Multiplication and division followed by addition and subtraction.

The second definition: operation from left to right.

Solution: Just simulate it. (The first one can be solved with stack, the second one can be done directly, and of course you can also use queue)

 

Space Golf (push physics formula)

 

There is No Alternative (minimum spanning tree correlation)

 

Flipping Parentheses  (segment tree + bisection)

<qj>

Title:

Given an initial string consisting of left and right parentheses, the initial string is guaranteed to be balanced.

q queries, flip the pos-th parenthesis, and ask you which leftmost parenthesis to flip would rebalance the sequence.

Each operation affects subsequent operations.

 

Ideas:

When encountering the problem of bracket balance, we usually think of prefix sum expression, but there is a flip (modification) operation in this problem, so it is not difficult to think that the data structure that can implement prefix sum + modification has a segment tree or tree-like array.

Due to the nature, the last parenthesis must be ')', and the prefix (last) value is 0, it will be balanced.

1.

If a ')' is flipped, the prefix sum from the beginning to the end of pos should be +2, and we can use the line segment tree to add +2 to the value of this interval.

Knowing that the string is to be balanced, the last position prefix sum should be 0, and currently the last position is 2.

Then we need to find a pos2 that flips pos2 so that the interval [pos2,n] is -2.

Then here in order not to destroy the balance, all values ​​in the interval must be greater than or equal to 2. Therefore, the line segment tree can maintain a minimum value of an interval. If the minimum value of the interval is not less than 2, the interval satisfies the condition.

How to find the leftmost pos, we can use binary search.

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

If the sum of all prefixes to the right of mid satisfies the condition, then we look for [l, mid] to the left, otherwise we look for [mid, n] to the right.

Complexity O(Q*logN*logN)

 

2.

Similar to above if '(' is flipped. The prefix sum at the last position should be -2.

How to find the leftmost bracket flip, and make the last position prefix sum to 0?

Flip the first ')' from the left.

If it is full of '(', it is not difficult to know that at the pos-th position, prefix(pos)==pos, indicating that ')' has not appeared before.

Same as above, just find the position of the first prefix(pos)!=pos by two points.

Complexity O(Q*logN*logN)

 

Above code:

#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\n",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\n",r);
                s[r]=')';
                update(r,n,-2,1,n,1);
            }
        }
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325529763&siteId=291194637