無向帶權圖,動態加邊(離線倒序轉化刪邊為加邊)。每次詢問:從 1 號點出發,路徑異或和有多少種不同值?
R。set),大小為 P。P * 2^R(每個路徑可任意組合環的線性基向量)。set。set 中所有路徑重新消元去重。z ^ a[x] ^ a[y] 插入線性基。若基更新,重構 set。set;遇到非樹邊同樣插入線性基並更新 set。// 線性基插入 + set 重構
void Gauss_Elimination(long long x) {
for (int i = 62; ~i; --i)
if ((x ^ basis[i]) < x) x ^= basis[i];
if (!x) return; // 無新向量
for (int i = 62; ~i; --i)
if (x >> i & 1) { basis[i] = x; break; }
// 重構 set
vector tmp(s.begin(), s.end());
s.clear();
for (auto v : tmp) s.insert(min(v, v ^ x));
}
// DFS 擴展連通塊
void DFS(int x, int from) {
vis[x] = 1;
a[x] = a[to] ^ w; // 路徑異或值
long long v = a[x];
for (int i = 62; ~i; --i) v = min(v, v ^ basis[i]);
s.insert(v);
for (edge e : adj[x])
if (e.id != (from ^ 1)) {
if (!vis[e.to]) DFS(e.to, e.id);
else Gauss_Elimination(e.w ^ a[x] ^ a[e.to]);
}
}
set(大小 ≤ n),總體 O(n log n log MAXW)。n ≤ 20000,log MAXW ≈ 63,常數優秀可過。set 去重必須在消元後進行,否則同值不同表示會重複。span 不變,min(v, v^x) 保證唯一表示。