> File Name: 5756.cpp > Author: jiangyuzhu > Mail: 834138558@qq.com > Created Time: 2016/9/28 16:26:35 ************************************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #include<set> #include<map> #include<algorithm> using namespace std; typedef long long ll; const int maxn = 2e5+ 5, maxm = 30 * maxn + 5, maxq = 2e5 + 5, oo = 0x3f3f3f3f; typedef pair<int, int>pi; pi pa[maxq]; int lson[maxm], rson[maxm]; struct EDGE{ int to, next; }edge[maxn]; int tot, num; int b[maxn]; int head[maxn]; ll sum[maxm]; int maxx[maxm], minn[maxm]; ll lazy[maxm]; int rt[maxn]; int n; int dfn; int depth[maxn], st[maxn], ed[maxn]; void init() { num = 0; tot = 0; dfn = 0; memset(head, -1, sizeof(head)); } void addedge(int from, int to) { edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } void push_up(int i, int l, int r) { sum[i] = sum[lson[i]] + sum[rson[i]] + (r - l + 1) * 1ll * lazy[i]; minn[i] = min(minn[lson[i]], minn[rson[i]]) + lazy[i]; maxx[i] = max(maxx[lson[i]], maxx[rson[i]]) + lazy[i]; } int build(int l, int r) { int root = ++dfn; lazy[root] = 0; int mid = l + r >> 1; if(l == r){ sum[root] = maxx[root] = minn[root] = depth[b[l]] - 1; lson[root] = rson[root] = 0; return root; } lson[root] = build(l, mid); rson[root] = build(mid + 1, r); push_up(root, l, r); return root; } int update(int root, int l, int r, int L, int R, int x) { int newroot = ++dfn; sum[newroot] = sum[root]; lazy[newroot] = lazy[root]; maxx[newroot] = maxx[root]; minn[newroot] = minn[root]; if(L == l && R == r){ lson[newroot] = lson[root]; rson[newroot] = rson[root]; lazy[newroot] += x; sum[newroot] += x * 1ll * (r - l + 1); maxx[newroot] += x; minn[newroot] += x; return newroot; } int mid = l + r >> 1; if(R <= mid){ lson[newroot] = update(lson[root], l, mid, L, R, x); rson[newroot] = rson[root]; }else if(L > mid){ rson[newroot] = update(rson[root], mid + 1, r, L, R, x); lson[newroot] = lson[root]; }else{ lson[newroot] = update(lson[root], l, mid, L, mid, x); rson[newroot] = update(rson[root], mid + 1, r, mid + 1, R, x); } push_up(newroot, l, r); return newroot; } ll query(int L, int R, int l, int r, int i, int id) { if(L == l && r == R){ if(id == 1) return sum[i]; else if(id == 2) return minn[i]; else return maxx[i]; } int mid = l + r >> 1; if(R <= mid){ ll tmp = query(L, R, l, mid, lson[i], id); if(id == 1) return tmp + (R - L + 1) * 1ll * lazy[i]; return tmp + lazy[i]; } else if(L > mid){ ll tmp = query(L, R, mid + 1, r, rson[i], id); if(id == 1) return tmp + (R - L + 1) * 1ll * lazy[i]; return tmp + lazy[i]; }else{ ll tmp1 = query(L, mid, l, mid, lson[i], id); ll tmp2 = query(mid + 1, R, mid + 1, r, rson[i], id); if(id == 1) return tmp1 + tmp2 + (R - L + 1) * 1ll * lazy[i]; else if(id == 2) return min(tmp1, tmp2) + lazy[i]; return max(tmp1, tmp2) + lazy[i]; } } void dfs(int u, int pa, int deep) { depth[u] = deep; st[u] = ++num; b[num] = u; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].to; if(v == pa) continue; dfs(v, u, deep + 1); } ed[u] = num; } void dfs1(int u, int pa) { for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].to; if(v == pa) continue; rt[v] = update(rt[u], 1, n, st[v], ed[v], -1); if(st[v] > 1) rt[v] = update(rt[v], 1, n, 1, st[v] - 1, 1); if(ed[v] < n) rt[v] = update(rt[v], 1, n, ed[v] + 1, n, 1); dfs1(v, u); } } int main (void) { int q; while(~scanf("%d%d", &n, &q)){ init(); int u, v; int a; for(int i = 0; i < n - 1; i++){ scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } dfs(1, 1, 1); rt[1] = build(1, n); dfs1(1, 1); ll ans = 0; for(int i = 0; i < q; ++i){ int k, p, t;scanf("%d%d%d", &k, &p, &t); p = (p + ans) % n + 1; bool flag = true; int totp = 0; for(int j = 0; j < k; ++j){ scanf("%d", &a); if(a > n) continue; pa[totp++] = pi(st[a], ed[a]); if(a == 1) flag = false; } if(!flag){ puts("-1"); ans = 0; continue; } pa[totp++] = pi(n + 1, n + 1); sort(pa, pa + totp); if(t == 1) ans = 0; else if(t == 2) ans = oo; else if(t == 3) ans = -oo; int l = 1; ll tmp; for(int j = 0; j < totp; j++){ if(l < pa[j].first){ tmp = query(l, pa[j].first - 1, 1, n, rt[p], t); if(t == 1) ans += tmp; else if(t == 2) ans = min(ans, tmp); else ans = max(ans, tmp); } l = max(l, pa[j].second + 1); } printf("%lld\n", ans); } } }
|