每次操作實際上相當於把點到根上所有點消除。$o()$暴力顯然,
用trie維護每棵子樹的後繼局面,然後需要進行trie樹異或操作和tire樹合併操作。
異或操作直接打標記
合併操作前,類似啟發式合併,先把子樹較小的的標記全部下放,然後全部按照另一棵的標記轉好,然後把它合併到另一顆裡面去。正確性因為有標記的地方都轉過,再轉一次就是原來的了。
複雜度$o(nlog^2n)$
#include #includeview code#include
#include
#include
using
namespace
std;
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define drep(i, r, l) for (int i = r; i >= l; i--)typedef
long
long
ll;const
int n = 100008, d = 20
;int
n, tot, head[n], tot, fa[n], sg[n], a[n], rt[n], ans[n];
bool rev[n][d + 5
];struct edgee[n << 1
];int
xgw;
inline
void add(int x, int
y)struct
node
t[n * (d + 5
)];inline
void updata(int
x)void insert(int u, int x, int d, int
num)
int p = (num & (1
<< d - 1)) ? 1 : 0
; p ^=rev[u][d];
if (!t[x].s[p]) t[x].s[p] = ++tot;
insert(u, t[x].s[p], d - 1
, num);
updata(x);
}void calc(int u, int d, int
num)
int find(int u, int x, int d, int
cur)
void turn(int u, int x, int
d)int merge(int u, int x, int v, int y, int
d) updata(x);
returnx;}
int merge(int u, int
v)void write(int u, int x, int d, int
cur)
int ls = t[x].s[0 ^ rev[u][d]], rs = t[x].s[1 ^rev[u][d]];
write(u, ls, d - 1
, cur);
write(u, rs, d - 1, cur + (1
<< d - 1
));}
void dfs(int
u)
int x = 0
;
for (int i = head[u], v; v = e[i].node, i; i =e[i].next)
if (v !=fa[u])
if (!a[u]) insert(u, rt[u] ? rt[u] : rt[u] = ++tot, d, x);
sg[u] = find(u, rt[u], d, 0);}
void tour(int u, int
cur)
void
solve()
}int
main()
solve();
#ifndef online_judge
fclose(stdin); fclose(stdout);
#endif
return0;
}
413 反轉整數
原題 您在真實的面試中是否遇到過這個題?是 給定x 123,返回 321 標籤 整數思路 按位依次取出數字存入陣列,再將數字取出乘以對應的權值完成反轉。注意反轉過程中隨時判斷數值是否超出int型範圍,超出範圍則返回0。參考 c int型負數除法取餘問題 ac class solution int s...
4 1 3 資料成員
資料成員用來說明物件特有的一些屬性,如人的身份證號 姓名 年齡 性別 身高 學歷,汽車的品牌 顏色 最高時速,蛋糕的名稱 尺寸 配料,書的名字 作者 isbn 出版社 出版日期,等等。資料成員大致可以分為兩類 屬於物件的資料成員和屬於類的資料成員。屬於物件的資料成員主要指在建構函式 init 中定義...
4 13 學習筆記
1.整數拆分為2 的冪的和 用陣列a 直接記錄結果。從前往後推的時候,有兩種可能性,分為a 2m 1 和a 2m 易知a 2m 1 a 2m 對於a 2m 它的所有拆分方式分為兩大類 1 含有1的,這部分所有方式都去掉1,就得到a 2m 1 2 不含有1的,也就是分出的都是2的倍數,那麼都除以2,就...