XOR TREE 牛客練習賽58 F 樹鏈剖分

2021-10-04 01:25:32 字數 2765 閱讀 7491

這個問題很容易想到之間的關係,假設現在所要查詢的這條鏈上有v1、v2、…… vk個點,那麼第i個點的貢獻在抑或**現的次數xor為

於是,如果k為偶數的時候,我們直接求這條鏈上所有值的抑或xor和即可,樹鏈剖分就可以很好的維護了。

所以考慮深度,會發現,深度奇偶不同的點一定是不相連線的,並且中間只隔了乙個點。於是,我們這裡開兩個線段樹,維護一下每個奇偶深度的抑或xor和。

這樣,我們查詢的時候,只用查詢於兩個結點的deep的奇偶不同的點的抑或和即可。

因為是奇數個點,所以也代表了兩個查詢結點一定是在深度上同奇偶。

#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #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()

return x;

}const int maxn = 2e5 + 7;

int n, q, a[maxn], head[maxn], cnt;

struct eddge

}edge[maxn << 1];

inline void addeddge(int u, int v)

inline void _add(int u, int v)

int siz[maxn], deep[maxn], wson[maxn], fa[maxn];

void dfs_1(int u, int father)

}}int top[maxn], dfn[maxn], tot, rid[maxn];

void dfs_2(int u, int topy)

}int tree[maxn << 2][3] = ;

inline void pushup(int rt)

void buildtree(int rt, int l, int r)

int mid = half;

buildtree(lson); buildtree(rson);

pushup(rt);

}void update(int rt, int l, int r, int qx, int val)

int mid = half;

if(qx <= mid) update(lson, qx, val);

else update(rson, qx, val);

pushup(rt);

}int s[3] = ;

void query(int rt, int l, int r, int ql, int qr)

int mid = half;

if(qr <= mid) query(ql);

else if(ql > mid) query(qr);

else

}inline int _lca(int u, int v)

if(deep[u] > deep[v]) swap(u, v);

return u;

}inline int range_query(int u, int v)

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

if(deep[u] < deep[v]) swap(u, v);

query(1, 1, n, dfn[v], dfn[u]);

ans = s[2];

}return ans;

}inline void init()

int main()

deep[0] = 0;

dfs_1(1, 0);

dfs_2(1, 1);

buildtree(1, 1, n);

int op, x, y;

while(q--)

else

}return 0;

}

牛客練習賽58 F

求帶單點修改的樹上兩點間任意子路徑長異或和。路徑長等於路徑上所有異或和。簡單模擬一下,可以發現。奇數情況下,答案是偶數點異或和。偶數情況下,就是正常的異或和。偶數點異或和也很容易處理。分深度奇偶樹狀陣列即可。但是這是對於鏈的,不能直接dfs dfsdf s序,需要剖分一下。但是我不會,所以去學了一下...

牛客練習賽58

a 給你兩個序列ai,bia i,b i ai bi 然後讓你兩兩配對相加,使得最大值最小。貪心。乙個從大到小排,乙個從小到大排,直接相加。b給你乙個01字串,然後讓你找到最多的組,滿足每一組都有0和1。貪心。從前往後掃。遇到0和1是立馬累加,思路 一開始想得是每次挑出行和列中的最大值,然後累加,沒...

牛客練習賽58 D 迷宮

乙個n m迷宮,迷宮中每個格仔用0或1表示,0表示該格仔可以通過,1表示該格仔是個障礙物,牛妹站在格仔 1,1 出口在格仔 n,m 牛妹想要走出迷宮,但牛妹只會按以下策略走 牛妹當前所在的格仔稱為當前格仔 如果當前格仔右邊沒有障礙物,牛妹就向右走,否則轉到2。如果當前格仔下方沒有障礙物,牛妹就向下走...