NOIAC41 最短路(線性基)
阿新 • • 發佈:2019-04-18
min make names () turn getchar() pre ring rst
/* 暴力可以st表維護線性基, 從而復雜度兩個log 實際上我們可以離線來做, 並且記錄可行最右值, 就是一個log的了 */ #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<iostream> #define ll long long #define mmp make_pair #define M 300010 using namespace std; int read() { int nm = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0'; return nm * f; } int n, m, Q, p[33], q[33], ans[M], w[M], l[M], d[M]; vector<int> note[M]; vector<pair<int, int> > to[M]; void dfs(int now, int f) { for(int i = 0; i < to[now].size(); i++) { int vj = to[now][i].first; if(vj == f) continue; d[vj] = d[now] ^ to[now][i].second; dfs(vj, now); } } int main() { n = read(), m = read(), Q = read(); for(int i = 1; i < n; i++) { int vi = read(), vj = read(), v = read(); to[vi].push_back(mmp(vj, v)); to[vj].push_back(mmp(vi, v)); } dfs(1, 0); for(int i = 1; i <= m; i++) w[i] = d[read()] ^ d[read()] ^ read(); for(int i = 1; i <= Q; i++) { ans[i] = d[read()] ^ d[read()]; l[i] = read(); note[read()].push_back(i); } for(int t = 1; t <= m; t++) { int x = w[t], r = t; for(int i = 30; i >= 0; i--) { if((x >> i) & 1) { if(!p[i]) { p[i] = x, q[i] = r; break; } if(q[i] < r) swap(p[i], x), swap(q[i], r); x ^= p[i]; } } for(int k = 0; k < note[t].size(); k++) { int v = note[t][k]; for(int i = 30; i >= 0; i--) if(q[i] >= l[v]) ans[v] = min(ans[v], ans[v] ^ p[i]); } } for(int i = 1; i <= Q; i++) { cout << ans[i] << "\n"; } return 0; }
NOIAC41 最短路(線性基)