XOR TREE cattle off the practice game [58 F] [tree] chain split

Topic Link


 This problem is easily the relationship between thought, there V1, V2, ...... VK points on this chain now assume to be queried, then the contribution of the i-th point in the number of XOR Or that appear to\large F(i) = (K - i) * i + i - 1

  • When K is an even number times, F (i) is an odd constant
  • When K is an odd number, F (i) when i is an even number F (i) is an odd number
  • Only F (i) is an odd number, when, in effect or whether only the XOR

  So, if K is an even number, we directly find all this chain of values ​​and to XOR Or, you can split the chain tree well maintained.

  If K is an odd time, we request 2,4,6, ...... these even-point Or and XOR. If we direct the segment tree maintenance course it is not enough, because dfs number is no such independence, there may be two points at the same time is even dfs sequence is linked together.

  So consider depth, will find different parity cell depth must be not connected and separated by only a point intermediate. So, we are here to open two tree line, maintain it or whether each of XOR parity and depth.

  Or it can be different and so, when we query, the query only two nodes deep parity point.

  Because it is an odd number of points, so it represents a two queries must be the same parity nodes in depth.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
#define MAX_3(a, b, c) max(a, max(b, c))
#define Rabc(x) x > 0 ? x : -x
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
inline int read()
{
    int x=0; char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') { x=(x<<1)+(x<<3)+c-'0'; c=getchar(); }
    return x;
}
const int maxN = 2e5 + 7;
int N, Q, a[maxN], head[maxN], cnt;
struct Eddge
{
    int nex, to;
    Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxN << 1];
inline void addEddge(int u, int v)
{
    edge[cnt] = Eddge(head[u], v);
    head[u] = cnt++;
}
inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
int siz[maxN], deep[maxN], Wson[maxN], fa[maxN];
void dfs_1(int u, int father)
{
    fa[u] = father; deep[u] = deep[father] + 1; Wson[u] = 0; siz[u] = 1;
    int maxx = 0;
    for(int i=head[u], v; ~i; i=edge[i].nex)
    {
        v = edge[i].to;
        if(v == father) continue;
        dfs_1(v, u);
        siz[u] += siz[v];
        if(maxx < siz[v])
        {
            maxx = siz[v];
            Wson[u] = v;
        }
    }
}
int top[maxN], dfn[maxN], tot, rid[maxN];
void dfs_2(int u, int topy)
{
    top[u] = topy;
    dfn[u] = ++tot; rid[tot] = u;
    if(Wson[u]) dfs_2(Wson[u], topy);
    for(int i=head[u], v; ~i; i=edge[i].nex)
    {
        v = edge[i].to;
        if(v == fa[u] || v == Wson[u]) continue;
        dfs_2(v, v);
    }
}
int tree[maxN << 2][3] = {0};
inline void pushup(int rt)
{
    tree[rt][2] = tree[lsn][2] ^ tree[rsn][2];
    tree[rt][0] = tree[lsn][0] ^ tree[rsn][0];
    tree[rt][1] = tree[lsn][1] ^ tree[rsn][1];
}
void buildTree(int rt, int l, int r)
{
    if(l == r)
    {
        tree[rt][deep[rid[l]] & 1] = a[rid[l]];
        tree[rt][2] = a[rid[l]];
        return;
    }
    int mid = HalF;
    buildTree(Lson); buildTree(Rson);
    pushup(rt);
}
void update(int rt, int l, int r, int qx, int val)
{
    if(l == r) { tree[rt][deep[rid[l]] & 1] = val; tree[rt][2] = val; return; }
    int mid = HalF;
    if(qx <= mid) update(Lson, qx, val);
    else update(Rson, qx, val);
    pushup(rt);
}
int s[3] = {0};
void query(int rt, int l, int r, int ql, int qr)
{
    if(ql <= l && qr >= r)
    {
        s[0] ^= tree[rt][0];
        s[1] ^= tree[rt][1];
        s[2] ^= tree[rt][2];
        return;
    }
    int mid = HalF;
    if(qr <= mid) query(QL);
    else if(ql > mid) query(QR);
    else { query(QL); query(QR); }
}
inline int _LCA(int u, int v)
{
    while(top[u] ^ top[v])
    {
        if(deep[top[u]] < deep[top[v]]) swap(u, v);
        u = fa[top[u]];
    }
    if(deep[u] > deep[v]) swap(u, v);
    return u;
}
inline int Range_Query(int u, int v)
{
    int ans = 0, lca = _LCA(u, v), len, op = (deep[u] & 1) ^ 1;
    int dis = deep[u] + deep[v] - 2 * deep[lca] + 1; dis &= 1;
    if(dis)
    {
        while(top[u] ^ top[v])
        {
            if(deep[top[u]] < deep[top[v]]) swap(u, v);
            len = deep[u] - deep[top[u]] + 1; len &= 1;
            s[0] = s[1] = s[2] = 0;
            query(1, 1, N, dfn[top[u]], dfn[u]);
            ans ^= s[op];
            u = fa[top[u]];
        }
        if(deep[u] < deep[v]) swap(u, v);
        len = deep[u] - deep[v] + 1; len &= 1;
        s[0] = s[1] = s[2] = 0;
        query(1, 1, N, dfn[v], dfn[u]);
        ans ^= s[op];
    }
    else
    {
        s[2] = 0;
        while(top[u] ^ top[v])
        {
            if(deep[top[u]] < deep[top[v]]) swap(u, v);
            query(1, 1, N, dfn[top[u]], dfn[u]);
            u = fa[top[u]];
        }
        if(deep[u] < deep[v]) swap(u, v);
        query(1, 1, N, dfn[v], dfn[u]);
        ans = s[2];
    }
    return ans;
}
inline void init()
{
    cnt = tot = 0;
    for(int i=1; i<=N; i++) head[i] = -1;
}
int main()
{
    N = read(); Q = read();
    init();
    for(int i=1; i<=N; i++) a[i] = read();
    for(int i=1, u, v; i<N; i++)
    {
        u = read(); v = read();
        _add(u, v);
    }
    deep[0] = 0;
    dfs_1(1, 0);
    dfs_2(1, 1);
    buildTree(1, 1, N);
    int op, x, y;
    while(Q--)
    {
        op = read(); x = read(); y = read();
        if(op == 1)
        {
            update(1, 1, N, dfn[x], y);
        }
        else
        {
            printf("%d\n", Range_Query(x, y));
        }
    }
    return 0;
}

 

Published 850 original articles · won praise 1012 · Views 110,000 +

Guess you like

Origin blog.csdn.net/qq_41730082/article/details/104923252