#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define ls i << 1
#define rs ls | 1
#define md (ll + rr >> 1)
#define inf 0x3f3f3f3f
#define mod 1000000007
#define N 100020
#define M 500020
int n, Q;
int fst[N], vv[M], nxt[M], e;
int st[N], ed[N], dep[N], lab[N], dc;
int sum[N*50], mx[N*50], mi[N*50], add[N*50], ch[N*50][2];
int rt[N], tot;
pii a[N*5];
void init(){
memset(fst, -1, sizeof fst); e = 0;
}
void adde(int u, int v){
vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
}
void dfs(int u, int p, int d){
dep[u] = d;
st[u] = ++dc;
lab[dc] = u;
for(int i = fst[u]; ~i; i = nxt[i]){
int v = vv[i];
if(v == p) continue;
dfs(v, u, d + 1);
}
ed[u] = dc;
}
void push_up(int i, int ll, int rr){
sum[i] = sum[ch[i][0]] + sum[ch[i][1]] + (rr - ll + 1) * add[i];
mx[i] = max(mx[ch[i][0]], mx[ch[i][1]]) + add[i];
mi[i] = min(mi[ch[i][0]], mi[ch[i][1]]) + add[i];
}
int build(int ll, int rr){
int k = ++tot;
if(ll == rr){
sum[k] = mx[k] = mi[k] = dep[lab[ll]] - 1;
ch[k][0] = ch[k][1] = add[k] = 0;
return k;
}
sum[k] = mx[k] = mi[k] = add[k] = 0;
ch[k][0] = build(ll, md);
ch[k][1] = build(md + 1, rr);
push_up(k, ll, rr);
return k;
}
int update(int l, int r, int v, int ll, int rr, int i){
int k = ++tot;
sum[k] = sum[i], add[k] = add[i];
mx[k] = mx[i], mi[k] = mi[i];
ch[k][0] = ch[i][0], ch[k][1] = ch[i][1];
if(l == ll && r == rr){
add[k] += v;
sum[k] += (r - l + 1) * v;
mx[k] += v;
mi[k] += v;
return k;
}
if(r <= md) ch[k][0] = update(l, r, v, ll, md, ch[i][0]);
else if(l > md) ch[k][1] = update(l, r, v, md + 1, rr, ch[i][1]);
else{
ch[k][0] = update(l, md, v, ll, md, ch[i][0]);
ch[k][1] = update(md + 1, r, v, md + 1, rr, ch[i][1]);
}
push_up(k, ll, rr);
return k;
}
void dfs1(int u, int p){
for(int i = fst[u]; ~i; i = nxt[i]){
int v = vv[i];
if(v == p) continue;
rt[v] = update(st[v], ed[v], -1, 1, n, rt[u]);
if(st[v] > 1)
rt[v] = update(1, st[v] - 1, 1, 1, n, rt[v]);
if(ed[v] < n)
rt[v] = update(ed[v] + 1, n, 1, 1, n, rt[v]);
dfs1(v, u);
}
}
int query(int l, int r, int t, int ll, int rr, int i){
if(l == ll && r == rr){
if(t == 1) return sum[i];
else if(t == 2) return mi[i];
else return mx[i];
}
if(r <= md){
int ret = query(l, r, t, ll, md, ch[i][0]);
if(t == 1) ret += (r - l + 1) * add[i];
else ret += add[i];
return ret;
}
else if(l > md){
int ret = query(l, r, t, md + 1, rr, ch[i][1]);
if(t == 1) ret += (r - l + 1) * add[i];
else ret += add[i];
return ret;
}
else{
int ret1 = query(l, md, t, ll, md, ch[i][0]);
int ret2 = query(md + 1, r, t, md + 1, rr, ch[i][1]);
if(t == 1) return ret1 + ret2 + (r - l + 1) * add[i];
if(t == 2) return min(ret1, ret2) + add[i];
if(t == 3) return max(ret1, ret2) + add[i];
}
}
int main(){
while(scanf("%d%d", &n, &Q) != EOF){
init();
for(int i = 1; i < n; ++i){
int u, v;
scanf("%d%d", &u, &v);
adde(u, v);
adde(v, u);
}
dc = 0;
dfs(1, -1, 1);
tot = 0;
rt[1] = build(1, n);
dfs1(1, -1);
int K, P, PP, t, ans = 0;
while(Q--){
scanf("%d%d%d", &K, &P, &t);
P = (P + ans) % n + 1;
bool ok = 0;
for(int i = 1; i <= K; ++i){
int x;
scanf("%d", &x);
a[i] = MP(st[x], ed[x]);
if(x == 1) ok = 1;
}
if(ok){
puts("-1"); ans = 0;
continue;
}
sort(a + 1, a + 1 + K);
a[++K] = MP(n + 1, n + 1);
if(t == 1) ans = 0;
if(t == 2) ans = inf;
if(t == 3) ans = -inf;
int pre = 1;
for(int i = 1; i <= K; ++i){
if(pre < a[i].first){
if(t == 1) ans += query(pre, a[i].first - 1, t, 1, n, rt[P]);
else if(t == 2)
ans = min(ans, query(pre, a[i].first - 1, t, 1, n, rt[P]));
else
ans = max(ans, query(pre, a[i].first - 1, t, 1, n, rt[P]));
}
pre = max(pre, a[i].second + 1);
}
printf("%d\n", ans);
}
}
return 0;
}
hdu 5756(主席树)
最新推荐文章于 2023-04-06 18:11:21 发布