[CF1149C](Tree Generator)

  • The meaning of problems

Tree sequence given in parentheses, there are m operation, two brackets each exchange, the exchange to ensure the order is still valid in parentheses after each operation output (operation not included) the diameter of the tree

  • solution

First conversion problem, a tree sequence for the bracket, we find some substrings meet most remaining brackets parentheses after erasing wherein the match, then the number in parentheses is the desired diameter of the remaining request

such a sequence tree brackets It is () (()) removed) ((, erasing the remaining three brackets matching parenthesis, the required diameter

But this is still not done nya, so we re-conversion value of 1 Imperial left parenthesis, right parenthesis is -1, the problem becomes to find two adjacent, so that after a period of pre-digital and digital and reduce some of the largest, the difference is the answer

Here you can think of this title cut

So the question has been transformed to do so, and for a range of problems to be repaired + + maintain some value related to range, we can use this simple tree line (Heavy secret) Data structure

For each segment tree node, the maximum value of the interval D before we Maintenance / rear min / max values, interval and, before all the answers and / suffix D value

D What value is it? We simply to draw a line within a specified interval, after the half and cut the first half and the largest, the difference is this range of values ​​D

  • code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define  rs (x<<1|1)
#define mid ((l+r)>>1)
#define N 200000
using namespace std;
struct zero{
int sum,prex,prem,sucx,sucm,pred,sucd,d,ans;
zero(){}
zero(int p1,int p2,int p3,int p4,int p5,int p6,int p7,int p8,int p9){sum=p1,prex=p2,prem=p3,sucx=p4,sucm=p5,pred=p6,sucd=p7,d=p8,ans=p9;}
}tree[N<<2];
// sum:区间和
// ans:区间答案
// pre/suc-x/m 区间 前/后 缀最 大/小 值
// pre/suc-d 前/后 缀 D值
// d 区间D 值 
const zero L=zero(1,1,0,1,0,1,1,1,1);
const zero R=zero(-1,0,-1,0,-1,1,1,1,1);
char input[N];
zero operator +(const zero &a,const zero &b){
    zero c;
    c.prex=max(a.prex,a.sum+b.prex);
    c.sucx=max(b.sucx,a.sucx+b.sum);
    c.prem=min(a.prem,a.sum+b.prem);
    c.sucm=min(b.sucm,a.sucm+b.sum);
    c.d=max(b.d-a.sum,a.d+b.sum);
    c.pred=max(a.pred,max(b.pred-a.sum,a.d+b.prex));
    c.sucd=max(b.sucd,max(b.sum+a.sucd,b.d-a.sucm));
    c.sum=a.sum+b.sum;
    c.ans=max(max(a.ans,b.ans),max(b.pred-a.sucm,a.sucd+b.prex));
    return c;
}
void build(int x,int l,int r){
    if(l==r){if(input[l]=='(')tree[x]=L;else tree[x]=R;return;}
    build(ls,l,mid),build(rs,mid+1,r);
    tree[x]=tree[ls]+tree[rs];
}
void update(int x,int l,int r,int pos){
    if(l==r){if(input[l]=='(')tree[x]=L;else tree[x]=R;return;}
    if(pos<=mid)update(ls,l,mid,pos);else update(rs,mid+1,r,pos);
    tree[x]=tree[ls]+tree[rs];
}
int n,m;
int main(){
    scanf("%d%d",&n,&m);n=(n-1)*2;
    scanf("%s",input+1);
    build(1,1,n);
    printf("%d\n",tree[1].ans);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        swap(input[a],input[b]);
        update(1,1,n,a),update(1,1,n,b);
        printf("%d\n",tree[1].ans);
    }
}

Guess you like

Origin www.cnblogs.com/stepsys/p/11580917.html