[SHOI2014] trigeminal nerve tree --LCT

Questions surface:

  BIG # 2187

Resolution:

   Clearly a need to modify a modification to the root of the chain, of course, maintain the chain of thought with LCT

  Partial results wanted, and had wanted to maintain separate virtual subtree entire subtree information and information found difficult to maintain. Then go out of self-study

  We define a point right point selected for its son nodes number $ 1 $

  Consider changing the point right point either its chain above the continuous $ 1 $ or continuous $ 2 $, so Splay each node are maintained can be the deepest than $ 1 $ point and not $ 2 $ point, then a range of changes and modifications single point, and engage directly in the Splay on the line

  Note that when the update sequence father node, first update with the right son, then left his son

 Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 500004, inf = 0x3f3f3f3f;

inline int read()
{
    int ret, f = 1;
    char c;
    while((c=getchar())&&(c<'0'||c>'9'))if(c=='-')f = -1;
    ret=c-'0';
    while((c=getchar())&&(c>='0'&&c<='9')) ret = (ret<<3)+(ret<<1)+c-'0';
    return ret*f;
}

int n, m, f[maxn<<1], a[maxn<<1], root, ans;
bool vis[maxn];

struct LCT{
    int fa, s[2], val;
    int nd1, nd2, add;
}tr[maxn]; 

int head[maxn], tot; 
struct edge{
    int nxt, to;
}e[maxn]; 

void Addedge(int x, int y)
{
    e[++tot] = (edge){head[x], y};
    head[x] = tot;
}

void dfs(int x)
{
    for(int i = head[x]; i; i = e[i].nxt)
    {
        int id = e[i].to;
        dfs(id);
        tr[x].val += (tr[id].val > 1);
    }
    tr[x].nd1 = (tr[x].val != 1? x: inf);
    tr[x].nd2 = (tr[x].val != 2? x: inf);
}

void update(int x)
{
    int ls = tr[x].s[0], rs = tr[x].s[1];
    if(rs && tr[rs].nd1 != inf)
        tr[x].nd1 = tr[rs].nd1;
    else if(tr[x].val != 1)
        tr[x].nd1 = x;
    else if(ls) 
        tr[x].nd1 = tr[ls].nd1;
    else 
        tr[x].nd1 = inf;

    if(rs && tr[rs].nd2 != inf)
        tr[x].nd2 = tr[rs].nd2;
    else if(tr[x].val != 2)
        tr[x].nd2 = x;
    else if(ls) 
        tr[x].nd2 = tr[ls].nd2;
    else 
        tr[x].nd2 = inf;
}

void spread(int x)
{
    int ls = tr[x].s[0], rs = tr[x].s[1];
    if(tr[x].add)
    {
        if(ls)
        {
            tr[ls].add += tr[x].add;
            tr[ls].val += tr[x].add;
            swap(tr[ls].nd1, tr[ls].nd2);
        }
        if(rs)
        {
            tr[rs].add += tr[x].add;
            tr[rs].val += tr[x].add;
            swap(tr[rs].nd1, tr[rs].nd2);
        }
        tr[x].add = 0;    
    }
}

bool isroot(int x)
{
    int ff = tr[x].fa;
    return tr[ff].s[0] != x && tr[ff].s[1] != x;
}

void Rotate(int x)
{
    int y = tr[x].fa, z = tr[y].fa, k = (tr[y].s[1] == x), w = (tr[z].s[1] == y), son = tr[x].s[k^1];
    if(!isroot(y))
        tr[z].s[w] = x;
    tr[y].s[k] = son;tr[son].fa = y;
    tr[x].s[k^1] = y;tr[y].fa = x;
    tr[x].fa = z;
    update(y);update(x);
}

void PushDown(int x)
{
    if(!isroot(x))    PushDown(tr[x].fa);
    spread(x);
}

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

void Access(int x)
{
    int pre = 0;
    while(x)
    {
        Splay(x);
        tr[x].s[1] = pre;
        update(x);
        pre = x;
        x = tr[x].fa;
    }
}

int main()
{
    n = read();
    for(int i = 1; i <= n; ++i)
    {
        int x;
        for(int j = 1; j <= 3; ++j)
        {
            x = read();
            if(x <= n)
            {
                tr[x].fa = i;
                Addedge(i, x);
                vis[x] = 1;
            }
            else
                f[x-n] = i;
        }
    }
    for(int i = 1; i <= (n<<1) + 1; ++i)
        a[i] = read(), tr[f[i]].val += a[i];
    for(int i = 1; i <= n; ++i)
        if(!vis[i])
        {
            root = i;
            dfs(i);
            break;
        }
    ans = (tr[root].val > 1);
    m = read();
    for(int i = 1; i <= m; ++i)    
    {
        int x = read();
        x -= n;
        Access(f[x]);
        Splay(f[x]);
        int now = (a[x] == 0? tr[f[x]].nd1: tr[f[x]].nd2), c = (a[x] == 0? 1: -1);
        if(now != inf)
        {
            Splay(now);
            tr[now].val += c;
            int rs = tr[now].s[1];
            if(rs)
            {
                tr[rs].val += c;
                tr[rs].add += c;
                swap(tr[rs].nd1, tr[rs].nd2);
                update(rs);
            }
            update(now);
        }
        else
        {
            tr[f[x]].val += c;
            tr[f[x]].add += c;
            ans ^= 1;
        }
        a[x] ^= 1;
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

Guess you like

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