Old Christmas Lights II
简要题意:求树上路径点权的最小差值。
题解:树上莫队转移+数据结构维护最小差值。
一开始用multiset,结果疯狂TLE。改成分块维护就过了。貌似块分小点跑的更快?
还可以用平衡树或者线段树维护,不过咱没有写。
1 #include<cassert> 2 #include<set> 3 #include<map> 4 #include<cmath> 5 #include<cstdio> 6 #include<iostream> 7 #include<algorithm> 8 using namespace std; 9 inline char nc() { 10 static char b[1<<16],*s=b,*t=b; 11 return s==t&&(t=(s=b)+fread(b,1,1<<16,stdin),s==t)?-1:*s++; 12 } 13 inline void read(int &x) { 14 char b = nc(); x = 0; 15 for (; !isdigit(b); b = nc()); 16 for (; isdigit(b); b = nc()) x = x * 10 + b - '0'; 17 } 18 const int N = 50005; 19 struct Edge {int v,n;} E[N*2]; 20 int n, m, head[N], ecnt, val[N], ans[N]; 21 int sz[N], son[N], fa[N], dep[N], top[N]; 22 int I[N], O[N], s[N*2], D, S, bl[N*2]; 23 bool oc[N]; 24 inline void ae(int u, int v) { 25 E[++ecnt] = (Edge){v, head[u]}; head[u] = ecnt; 26 E[++ecnt] = (Edge){u, head[v]}; head[v] = ecnt; 27 } 28 inline int ABS(int x) {return x > 0 ? x : -x;} 29 void dfs1(int u, int f) { 30 sz[u] = 1; fa[u] = f; dep[u] = dep[f] + 1; 31 for (int v, i = head[u]; i; i = E[i].n) if ((v = E[i].v) != f) { 32 dfs1(v, u); sz[u] += sz[v]; if (sz[son[u]] < sz[v]) son[u] = v; 33 } 34 } 35 void dfs2(int u, int tp) { 36 I[u] = ++D; s[D] = u; 37 top[u] = tp; if (son[u]) dfs2(son[u], tp); 38 for (int v, i = head[u]; i; i = E[i].n) 39 if (v = E[i].v, v != fa[u] && v != son[u]) dfs2(v, v); 40 O[u] = ++D; s[D] = u; 41 } 42 int findLca(int a, int b) { 43 for (; top[a] != top[b]; a = fa[top[a]]) 44 if (dep[top[a]] < dep[top[b]]) swap(a, b); 45 return dep[a] < dep[b] ? a : b; 46 } 47 struct QA { 48 int l, r, e, id; 49 inline void init(int u, int v, int i) { 50 id = i; if (I[u] > I[v]) swap(u, v); 51 e = findLca(u, v); 52 if (u == e) e = 0, l = I[u], r = I[v]; 53 else l = O[u], r = I[v]; 54 if (l > r) swap(l, r); 55 } 56 inline bool operator<(const QA &q) const { 57 if (bl[l] != bl[q.l]) return bl[l] < bl[q.l]; 58 return r < q.r; 59 } 60 } q[N]; 61 namespace MN { 62 #define fir first 63 #define sec second 64 typedef long long ll; 65 const ll inf = 1e10; 66 pair < int , int > v[N]; 67 int H, r[N], cnt[N], S, bl[N], B; 68 ll mx[5000], mn[5000], w[5000]; 69 template < class T1, class T2 > inline void gmax(T1 &x, T2 y) {if (x < y) x = y;} 70 template < class T1, class T2 > inline void gmin(T1 &x, T2 y) {if (x > y) x = y;} 71 inline void init() { 72 for (int i = 1; i <= n; ++i) v[i].fir = val[i], v[i].sec = i; 73 sort(v + 1, v + 1 + n); H = 0; 74 for (int i = 1; i <= n; ++i) { 75 if (v[i].fir != v[i-1].fir) r[++H] = v[i].fir; 76 val[v[i].sec] = H; 77 } S = max(1.0, sqrt(H / 5)); B = (H - 1) / S + 1; 78 for (int i = 1; i <= H; ++i) bl[i] = (i - 1) / S + 1; 79 for (int i = 1; i <= B; ++i) mx[i] = -inf, mn[i] = inf, w[i] = inf; 80 } 81 inline void addv(int x) { 82 if (++cnt[x] == 1) { 83 for (int i = x + 1; bl[i] == bl[x]; ++i) 84 if (cnt[i]) {gmin(w[bl[x]], (r[i] - r[x])); break;} 85 for (int i = x - 1; bl[i] == bl[x]; --i) 86 if (cnt[i]) {gmin(w[bl[x]], (r[x] - r[i])); break;} 87 gmax(mx[bl[x]], r[x]); gmin(mn[bl[x]], r[x]); 88 assert(w[bl[x]] >= 0); 89 } else if (cnt[x] > 1) w[bl[x]] = 0; 90 } 91 inline void delv(int x) { 92 if (--cnt[x] < 2) { 93 ll p = -inf; int b = bl[x]; mx[b] = -inf, mn[b] = w[b] = inf; 94 for (int i = (b - 1) * S + 1; i < b * S + 1 && i <= H; ++i) if (cnt[i]) { 95 gmax(mx[b], r[i]), gmin(mn[b], r[i]); 96 gmin(w[b], ll(r[i]) - p); p = r[i]; 97 assert(w[b] >= 0); 98 if (cnt[i] > 1) w[b] = 0; 99 } 100 } 101 } 102 inline ll query() { 103 ll res = w[1], p = mx[1], t; 104 for (int i = 2; i <= B; ++i) { 105 gmin(res, w[i]); 106 assert(res >= 0); 107 t = mn[i] - p; 108 gmin(res, t); // add uint here after debug 109 assert(res >= 0); 110 gmax(p, mx[i]); 111 } return res; 112 } 113 }; 114 using MN::addv; 115 using MN::delv; 116 using MN::query; 117 inline void updn(int u) { 118 if (oc[u] ^= 1) addv(val[u]); else delv(val[u]); 119 } 120 void solve() { 121 sort(q, q + m); 122 for (int l = 1, r = 0, i = 0; i < m; ++i) { 123 //printf("%d %d %d %d\n", q[i].l, q[i].r, q[i].e, q[i].id); 124 while (r < q[i].r) updn(s[++r]); 125 while (r > q[i].r) updn(s[r--]); 126 while (l < q[i].l) updn(s[l++]); 127 while (l > q[i].l) updn(s[--l]); 128 if (q[i].e) updn(q[i].e); 129 ans[q[i].id] = query(); 130 if (q[i].e) updn(q[i].e); 131 } 132 for (int i = 0; i < m; ++i) printf("%d\n", ans[i]); 133 } 134 int main() { 135 read(n); read(m); S = sqrt(n * 2) + 1; 136 for (int i = 1; i <= n * 2; ++i) bl[i] = (i - 1) / S + 1; 137 for (int i = 1; i <= n; ++i) read(val[i]); 138 MN::init(); 139 for (int u, v, i = 1; i < n; ++i) read(u), read(v), ae(u, v); 140 dfs1(1, 1); dfs2(1, 1); 141 for (int u, v, i = 0; i < m; ++i) read(u), read(v), q[i].init(u, v, i); 142 //for (int i = 1; i <= n * 2; ++i) printf("%d ", s[i]); puts(""); 143 solve(); 144 return 0; 145 }