首页 > 代码库 > BZOJ3757 苹果树
BZOJ3757 苹果树
树上的莫队算法。。。话说糖果公园也是的说?、、、蒟蒻不会233
先搞出dfs序,然后对dfs序直接莫队就好了。。。
但是写的我蛋疼啊。。。3h就一道题还让不让人活?
1 /************************************************************** 2 Problem: 3757 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:4000 ms 7 Memory:23096 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <cmath> 13 #include <algorithm> 14 15 using namespace std; 16 const int N = 100005; 17 const int Maxlen = 3500005; 18 19 int n, Q; 20 int tot, first[N]; 21 int dfn, c[N], w[N << 1]; 22 int sz, pos[N << 1]; 23 int l, r, Lca; 24 int sum, cnt[N], ans[N]; 25 bool vis[N << 1]; 26 char buf[Maxlen], *C = buf; 27 int Len; 28 29 struct tree_node { 30 int dep, fa[20]; 31 bool vis; 32 int st, en; 33 } tr[N]; 34 35 struct edges { 36 int next, to; 37 edges() {} 38 edges(int _n, int _t) : next(_n), to(_t) {} 39 } e[N << 1]; 40 41 struct query { 42 int l, r, lca, a, b, id; 43 44 inline bool operator < (const query &b) const { 45 return pos[l] == pos[b.l] ? r < b.r : pos[l] < pos[b.l]; 46 } 47 }a[N]; 48 49 void Add_Edges(int x, int y) { 50 e[++tot] = edges(first[x], y), first[x] = tot; 51 e[++tot] = edges(first[y], x), first[y] = tot; 52 } 53 54 inline int read() { 55 int x = 0; 56 while (*C < ‘0‘ || ‘9‘ < *C) ++C; 57 while (‘0‘ <= *C && *C <= ‘9‘) 58 x = x * 10 + *C - ‘0‘, ++C; 59 return x; 60 } 61 62 void dfs(int p) { 63 int x, y; 64 w[tr[p].st = ++dfn] = p, tr[p].vis = 1; 65 for (x = 1; x <= 17; ++x) 66 tr[p].fa[x] = tr[tr[p].fa[x - 1]].fa[x - 1]; 67 for (x = first[p]; x; x = e[x].next) 68 if (!tr[y = e[x].to].vis) 69 tr[y].dep = tr[p].dep + 1, tr[y].fa[0] = p, dfs(y); 70 w[tr[p].en = ++dfn] = p; 71 } 72 73 inline int lca(int x, int y) { 74 int i; 75 if (x == y) return x; 76 if (tr[x].dep < tr[y].dep) swap(x, y); 77 for (i = 17; i >= 0; --i) 78 if (tr[tr[x].fa[i]].dep >= tr[y].dep) x = tr[x].fa[i]; 79 if (x == y) return x; 80 for (i = 17; i >= 0; --i) 81 if (tr[x].fa[i] != tr[y].fa[i]) x = tr[x].fa[i], y = tr[y].fa[i]; 82 return tr[x].fa[0]; 83 } 84 85 inline int check(int x, int y) { 86 return x != y && cnt[x] && cnt[y]; 87 } 88 89 inline void update(int x) { 90 if (vis[x]) { 91 if (!(--cnt[c[x]])) --sum; 92 } else 93 if (!(cnt[c[x]]++)) ++sum; 94 vis[x] ^= 1; 95 } 96 97 int main() { 98 Len = fread(C, 1, Maxlen, stdin); 99 buf[Len] = ‘\0‘;100 int i, x, y;101 n = read(), Q = read();102 for (i = 1; i <= n; ++i)103 c[i] = read();104 for (i = 1; i <= n; ++i) {105 x = read(), y = read();106 if (x && y) Add_Edges(x, y);107 }108 tr[1].dep = 1;109 dfs(1);110 111 sz = (int) sqrt(n * 2 + 0.5);112 for (i = 1; i <= dfn; ++i)113 pos[i] = (i - 1) / sz + 1;114 for (i = 1; i <= Q; ++i) {115 x = read(), y = read();116 a[i].a = read(), a[i].b = read(), a[i].id = i;117 if (tr[x].st > tr[y].st) swap(x, y);118 Lca = lca(x, y);119 if (Lca == x)120 a[i].l = tr[x].st, a[i].r = tr[y].st;121 else a[i].l = tr[x].en, a[i].r = tr[y].st, a[i].lca = Lca;122 }123 124 sort(a + 1, a + Q + 1);125 for (i = 1, l = 1, r = 0; i <= Q; ++i) {126 while (r < a[i].r) update(w[++r]);127 while (r > a[i].r) update(w[r--]);128 while (l < a[i].l) update(w[l++]);129 while (l > a[i].l) update(w[--l]);130 if (a[i].lca) update(a[i].lca);131 ans[a[i].id] = sum - check(a[i].a, a[i].b);132 if (a[i].lca) update(a[i].lca);133 }134 for (i = 1; i <= Q; ++i)135 printf("%d\n", ans[i]);136 return 0;137 }
BZOJ3757 苹果树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。