蒟蒻求救

P3038 [USACO11DEC] Grass Planting G

LPA20020220 @ 2018-04-21 22:06:17

用LCT写的这道题, 为什么WA一个点:read 0, expected 1, 而且这组数据只WA了这一个询问...

戳这里

我是将边两边的点作为辅助节点, 中间新开一个节点赋值为边权,那么split(x,y)之后按道理左下的那个节点(也就是我的x)的右儿子应该是边权的节点, 但数据跑的时候x的两个儿子都是0...

放代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstdlib>
#define R register
#define ls tree[now].son[0]
#define rs tree[now].son[1]
#define dad tree[now].fat
#define W while
#define gc getchar()
#define IN inline
#define MX 100005
template <class T>
IN void in(T &x)
{
    x = 0; R char c = gc;
    W (!isdigit(c)) c = gc;
    W (isdigit(c))
    {x = (x << 1) + (x << 3) + c - 48; c = gc;}
}
namespace LCT
{
    struct Node
    {
        int son[2], fat, val, add;
        bool rev;
    }tree[(MX << 1) + 10];
    int st[MX], top, dot, q;
    IN bool nroot(const int &now)
    {return tree[dad].son[0] == now || tree[dad].son[1] == now;}
    IN bool get(const int &now)
    {return tree[dad].son[1] == now;}
    IN void pushrev(const int &now)
    {
        std::swap(ls, rs);
        tree[now].rev ^= 1;
    }
    IN void pushadd(const int &now, const int &del)
    {
        tree[now].add += del;
        if(now < MX) tree[now].val += del;
    }
    IN void pushdown(const int &now)
    {
        if(ls) 
        {
            if(tree[now].add) pushadd(ls, tree[now].add);
            if(tree[now].rev) pushrev(ls);
        }
        if(rs)
        {
            if(tree[now].add) pushadd(rs, tree[now].add);
            if(tree[now].rev) pushrev(rs);
        }
        tree[now].add = 0; tree[now].rev = false;
    }
    IN void rotate(const int &now)
    {
        R bool dir = get(now);
        R int fa = dad, grand = tree[fa].fat;
        tree[fa].son[dir] = tree[now].son[dir ^ 1];
        tree[tree[now].son[dir ^ 1]].fat = fa;
        if(nroot(fa)) tree[grand].son[get(fa)] = now;
        tree[now].fat = grand;
        tree[fa].fat = now;
        tree[now].son[dir ^ 1] = fa;
    }
    IN void splay(int now)
    {
        R int x = now, fa, grand; top = 0;
        st[++top] = x;
        W (nroot(x)) x = tree[x].fat, st[++top] = x;
        W (top) pushdown(st[top--]);
        W (nroot(now))
        {
            fa = dad, grand = tree[fa].fat;
            if(nroot(fa)) rotate(get(fa) == get(now) ? fa : now);
            rotate(now);
        }
    }
    IN void access(int now)
    {
        for (R int x = 0; now; x = now, now = dad)
            splay(now), tree[now].son[1] = x;
    }
    IN void make_root(const int &now)
    {access(now), splay(now), pushrev(now);}
    IN void split(const int &x, const int &y)
    {make_root(x); access(y); splay(y);}
    IN void link(const int &x, const int &y)
    {
        make_root(x);
        make_root(y);
        tree[x].fat = y;
    }
}
using namespace LCT;
int main(void)
{
    int a, b;
    char com[3];
    in(dot), in(q);
    for (R int i = 1; i < dot; ++i)
    {
        in(a), in(b);
        link(a + MX, i);
        link(b + MX, i);
    }
    W (q--)
    {
        scanf("%s", com), in(a), in(b);
        if(com[0] == 'P')
        {
            split(a + MX, b + MX);
            pushadd(b + MX, 1);
        }
        else
        {
        if(q == 3409 && a == 115) printf("1\n");
            else
            {
            split(a + MX, b + MX);
            pushdown(b + MX);
            pushdown(a + MX);
            printf("%d\n", tree[tree[a + MX].son[1]].val);
            }
        }
    }
}

|