[HNOI2011] brackets repair --Splay

Face questions

   Bzoj2329

Resolve

   To support the interval flip, you can think of the Splay

  But what information you want to get the answer to maintain it, the ")" as 1 "(" as -1, and the largest prefix denoted as $ lx $, and the smallest suffix for the $ rn $, then  $ ans = \ left \ lceil \ FRAC {LX} {2} \ right \ rceil + \ left \ lceil \ left | \ FRAC {RN} {2} \ right | \ right \ rceil $ , thus maintaining the prefix and maximum $ lx $, suffixes minimum and $ rn $, but because of the range and turned over to the counter-operations, but also need to maintain a minimum prefix and $ ln $, suffixes and maximum $ rx $, updated way Splay seeking the most sub-segment and the same time, as shown:

 

 

  Can find the answer, but there is one thing to consider is the impact between the mark and the mark, that mark the order when decentralization. Clearly mark need to cover decentralization, it needs to flip the son negated mark cleared; followed by the first or the first inverted flip it? Virtually no influence between the two marks, regardless of which second decentralization will do, I follow the title sequence, marking the second flip decentralization, devolution negated final mark

 Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn = 100006, inf = INT_MAX;

template<class T> void read(T &re)
{
    re=0;
    T sign=1;
    char tmp;
    while((tmp=getchar())&&(tmp<'0'||tmp>'9')) if(tmp=='-') sign=-1;
    re=tmp-'0';
    while((tmp=getchar())&&(tmp>='0'&&tmp<='9')) re=(re<<3)+(re<<1)+(tmp-'0');
    re*=sign;
}

int n, m, root;
int a[maxn];
char ch[maxn];

struct splay_tree{
    int s[2], fa, val, lx, rx, ln, rn, cov, rev, opp, sum, siz;
}tr[maxn];

void Cover(int now, int x)
{
    tr[now].val = x;
    tr[now].sum = tr[now].siz * tr[now].val;
    tr[now].lx = max(0, tr[now].sum);
    tr[now].rx = max(0, tr[now].sum);
    tr[now].ln = min(0, tr[now].sum);
    tr[now].rn = min(0, tr[now].sum);
    tr[now].cov = tr[now].val;
    tr[now].rev = tr[now].opp = 0;
}

void Reverse(int now)
{
    swap(tr[now].s[0], tr[now].s[1]);
    swap(tr[now].lx, tr[now].rx);
    swap(tr[now].ln, tr[now].rn);
    tr[now].rev ^= 1;
}

void Oppsit(int now)
{
    swap(tr[now].lx, tr[now].ln);
    swap(tr[now].rx, tr[now].rn);
    tr[now].lx *= -1;
    tr[now].rx *= -1;
    tr[now].ln *= -1;
    tr[now].rn *= -1;
    tr[now].val *= -1;
    tr[now].sum *= -1;
    tr[now].opp ^= 1;
}

void spread(int x)
{
    int ls = tr[x].s[0], rs = tr[x].s[1];
    if(tr[x].cov)
    {
        if(ls)
            Cover(ls, tr[x].cov);
        if(rs)
            Cover(rs, tr[x].cov);
        tr[x].cov = 0;
    }
    if(tr[x].rev)
    {
        if(ls)
            Reverse(ls);
        if(rs)
            Reverse(rs);
        tr[x].rev = 0;
    }
    if(tr[x].opp)
    {
        if(ls)
            Oppsit(ls);
        if(rs)
            Oppsit(rs);
        tr[x].opp = 0;
    }
}

void update(int x)
{
    int ls = tr[x].s[0], rs = tr[x].s[1];
    tr[x].sum = tr[ls].sum + tr[rs].sum + tr[x].val;
    tr[x].siz = P [ls] .siz + tr [rs] .siz + 1 ; 
    p [x] .lx = max (p [ls] .lx, p [ls] .sum + p [x] .val + tr [rs] .lx); 
    p [x] .rx = max (p [rs] .rx, tr [rs] .sum + p [x] .val + p [ls] .rx); 
    p [x] .ln = min (p [ls] .ln, p [ls] .sum + p [x] .val + tr [rs] .ln); 
    p [x] rn = min (p [rs] rn, p [rs] .sum + p [x] .val + p [ls] rn); 
} 

Void rotate ( int x) 
{ 
    int y = p [x] .fa, z = p [y] .fa, k = (p [y] .S [ 1 ] == x), w = (p [z ] .S [ 1 ] == y), son = p [x] .S [k ^ 1 ]; 
    spread(y);spread(x);
    tr [y] .S [k] = lip; tr [son] .fa = y;
    tr[x].s[k^1] = y;tr[y].fa = x;
    tr[z].s[w] = x;tr[x].fa = z;
    update(y);update(x);
}

void Splay(int x, int to)
{
    int y, z;
    while(tr[x].fa != to)
    {
        y = tr[x].fa;
        z = tr[y].fa;
        if(z != to)
            Rotate((tr[y].s[0] == x) ^ (tr[z].s[0] == y)? x: y);
        Rotate(x);
    }
    if(!to)
        root = x;
}

void Build(int l, int r, int ff)
{
    int mid = (l + r)>>1;
    if(l < mid)
        Build(l, mid - 1, mid);
    if(mid < r)
        Build(mid + 1, r, mid);
    if(ff)
        tr[ff].s[ff < mid] = mid;
    tr[mid].fa = ff;
    tr[mid].val = a[mid];
    update(mid);
}

int Find(int x)
{
    int now = root;
    while(1)
    {
        spread(now);
        int ls = tr[now].s[0], rs = tr[now].s[1];
        if(tr[ls].siz + 1 == x)
            return now;
        if(x <= tr[ls].siz)
            now = ls;
        else
            x -= tr[ls].siz + 1, now = rs;
    }
}

int main()
{
    read(n);read(m);
    scanf("%s", ch);
    for(int i = 1; i <= n; ++i)
        a[i+1] = (ch[i-1] == ')'? 1: -1);
    n += 2;
    Build(1, n, 0);
    tr[0].s[1] = root = (1 + n)>>1;
    for(int i = 1; i <= m; ++i)
    {
        //cout<<i<<endl;
        char opt[10];
        scanf("%s", opt);
        if(opt[0] == 'R')
        {
            int x, y;
            char c[2];
            read(x);read(y);
            scanf("%s", c);
            y += 2;
            x = Find(x);
            y = Find(y);
            Splay(x, 0);
            Splay(y, x);
            int now = tr[y].s[0];
            Cover(now, (c[0] == ')'? 1: -1));
            update(y);update(x);
        }
        else if(opt[0] == 'S')
        {
            int x, y;
            read(x);read(y);
            y += 2;
            x = Find(x);
            y = Find(y);
            Splay(x, 0);
            Splay(y, x);
            int now = tr[y].s[0];
            Reverse(now);
        }
        else if(opt[0] == 'I')
        {
            int x, y;
            read(x);read(y);
            y += 2;
            x = Find(x);
            y = Find(y);
            Splay(x, 0);
            Splay(y, x);
            int now = tr[y].s[0];
            Oppsit(now);
            update(y);update(x);
        }
        else
        {
            int x, y;
            read(x);read(y);
            y += 2;
            x = Find(x);
            y = Find(y);
            Splay(x, 0);
            Splay(y, x);
            int now = tr[y].s[0];
            printf("%d\n", (tr[now].lx + 1) / 2 + (abs(tr[now].rn) + 1) / 2);
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Joker-Yza/p/11366963.html