主要想法:假设给你足够时间,那么就可以对每个点建议一颗线段树来查询了,但是需要将点全部按照某个特定的序列存进线段树,如代码是以树的深搜顺序作为指定顺序,这样以来我们既可以将数据查询分成诺干个区间进行查询了,减少了大量查询。那么这样你都知道了,其实只需要利用主席树将每个点的情况都存进去主席树里面,因为对于相邻的点来说有着太多的重复情况了,所以我们可以利用这个数据结构来优化时间。

#include<bits/stdc++.h>
#define mm ((l + r) >> 1)
#define inf 0x3f3f3f3f
#define maxn 100070
#define maxm 5000700
using namespace std; vector<int>Gra[maxn];
pair<int, int>a[maxn];
int st[maxn], ed[maxn], dep[maxn], lab[maxn], rt[maxn];
int sum[maxm], mi[maxm], ma[maxm], add[maxm], ch[maxm][];
int N, Q, ntr, tot, lastans, bb, aa; ///求深度、设置编号顺序
void dfs1(int u, int no, int d){
dep[u] = d;
st[u] = ++ntr;
lab[ntr] = u;
for(int i = Gra[u].size() - ; i >= ; i--){
int v = Gra[u][i];
if(v != no) dfs1(v, u, d + );
}
ed[u] = ntr;
} ///数据跟新
void push_up(int rt, int l, int r){
sum[rt] = sum[ch[rt][]] + sum[ch[rt][]] + (r - l + ) * add[rt];
ma[rt] = max(ma[ch[rt][]], ma[ch[rt][]]) + add[rt];
mi[rt] = min(mi[ch[rt][]], mi[ch[rt][]]) + add[rt];
} ///建树
int buildTree(int l, int r){
int rt = ++tot;
if(l == r){
sum[rt] = ma[rt] = mi[rt] = dep[lab[l]] - ;
ch[rt][] = ch[rt][] = add[rt] = ;
return rt;
}
sum[rt] = ma[rt] = mi[rt] = add[rt] = ;
ch[rt][] = buildTree(l, mm);
ch[rt][] = buildTree(mm + , r);
push_up(rt, l, r);
return rt;
} ///更新区间、 更新值、 实际区间、 旧的数据点
int update(int ll, int rr, int v, int l, int r, int old){
int rt = ++tot;
sum[rt] = sum[old]; add[rt] = add[old];
ma[rt] = ma[old]; mi[rt] = mi[old];
ch[rt][] = ch[old][]; ch[rt][] = ch[old][];
if(ll == l && rr == r){
add[rt] += v;
sum[rt] += (rr - ll + ) * v;
ma[rt] += v;
mi[rt] += v;
return rt;
}
if(rr <= mm) ch[rt][] = update(ll, rr, v, l, mm, ch[old][]);
else if(ll > mm) ch[rt][] = update(ll, rr, v, mm + , r, ch[old][]);
else{
ch[rt][] = update(ll, mm, v, l, mm, ch[old][]);
ch[rt][] = update(mm + , rr, v, mm + , r, ch[old][]);
}
push_up(rt, l, r);
return rt;
} ///遍历所有点为每个点在主席树中植入一个版本。关于以该点根的情况。
void dfs2(int u, int no){
for(int i = Gra[u].size() - ; i >= ; i --){
int v = Gra[u][i];
if(v == no) continue;
rt[v] = update(st[v], ed[v], -, , N, rt[u]);
if(st[v] > ) rt[v] = update(, st[v] - , , , N, rt[v]);
if(ed[v] < N) rt[v] = update(ed[v] + , N, , , N, rt[v]);
dfs2(v, u);
}
} ///相当于查询关于某个点版本的线段树
int query(int ll, int rr, int t, int l, int r, int rt){
if(l == ll && r == rr){
if(t == ) return sum[rt];
else if(t == ) return mi[rt];
else return ma[rt];
}
if(rr <= mm){
int ret = query(ll, rr, t, l, mm, ch[rt][]);
if(t == ) return ret + (rr - ll + ) * add[rt];
else return ret + add[rt];
}else if(ll > mm){
int ret = query(ll, rr, t, mm + , r, ch[rt][]);
if(t == ) return ret + (rr - ll + ) * add[rt];
else return ret + add[rt];
}else{
int retl = query(ll, mm, t, l, mm, ch[rt][]);
int retr = query(mm + , rr, t, mm + , r, ch[rt][]);
if(t == ) return retl + retr + (rr - ll + ) * add[rt];
if(t == ) return min(retl, retr) + add[rt];
if(t == ) return max(retl, retr) + add[rt];
}
} int main(){
while(~scanf("%d%d",&N,&Q)){
for(int i = ; i <= N; i ++) Gra[i].clear();
for(int i = ; i < N; i ++){
scanf("%d%d",&aa,&bb);
Gra[aa].push_back(bb);Gra[bb].push_back(aa);
}
lastans = tot = ntr = ;
dfs1(, -, );
rt[] = buildTree(, N);
dfs2(, -); int K, T, P, x;
while(Q -- ){
scanf("%d%d%d", &K, &P, &T);
P = (lastans + P) % N + ;
bool rootsign = false;
for(int i = ; i < K; i ++){
scanf("%d", &x);
a[i] = make_pair(st[x], ed[x]);
rootsign = x == ? true : rootsign;
}
if(rootsign){
printf("-1\n");
lastans = ;
continue;
}
sort(a, a + K);
a[K ++] = make_pair(N + , N + );
///排完序之后按照中间空开的区间查询关于某个点的某种数据
if(T == ) lastans = ;
else if(T == ) lastans = inf;
else lastans = -inf;
int pre = ;
for(int i = ; i < K; i ++){
if(pre < a[i].first){
int tmp = query(pre, a[i].first - , T, , N, rt[P]);
if(T == ) lastans += tmp;
else if(T == ) lastans = min(lastans, tmp);
else lastans = max(lastans, tmp);
}
pre = max(pre, a[i].second + );
}
printf("%d\n",lastans);
}
}
return ;
}

Boss Bo (主席树)的更多相关文章

  1. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  2. 主席树:HDU 4417 Super Mario

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )

    树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...

  4. bzoj 1901 主席树+树状数组

    修改+查询第k小值 单纯主席树修改会打乱所有,所以再套一个树状数组维护前缀和使得修改,查询都是log 对了,bzoj上不需要读入组数,蜜汁re.. #include<cstdio> #in ...

  5. Super Mario HDU - 4417 (主席树)

    Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...

  6. hdu 4417 Super Mario 树状数组||主席树

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Prob ...

  7. Super Mario(主席树)

    Super Mario  Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded ...

  8. hdu4417 主席树求区间小于等于K

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417   Problem Description Mario is world-famous plum ...

  9. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

随机推荐

  1. MovieLens电影数据分析

    下载数据包 链接:https://grouplens.org/datasets/movielens/1m/ 解压: 四个文件分别是数据介绍,电影数据表,电影评分表,用户表 进行电影数据分析 进入ipy ...

  2. vue中watch的详细用法

    在vue中,使用watch来响应数据的变化.watch的用法大致有三种.下面代码是watch的一种简单的用法: <input type="text" v-model=&quo ...

  3. 【F12】谷歌浏览器--前台效果可以在不访问服务器的前提下直接改样式看效果是否是预期值。

    F12-前台效果可以在不访问服务器的前提下直接改样式看效果是否是预期值. 1.Element---页面所有元素,通过它可以做selenium的元素定位,删除页面元素,增加页面属性(通过增加页面属性便于 ...

  4. 帝国cms调用相关文章若没有则调取最新文章

    前面我们说了帝国cms调用最新文章 利用文字调用标签phomenews,现在我们说下相关文章的调用,如果文章有设置关键词的话可以直接用[!--other.link--]进行调取,现在我们来升级一下,如 ...

  5. RN无限轮播以及ScrollView的大小调节问题

    如果你的ScrollView的大小是全屏,height不能用,这种情况需要给ScrollView添加一个容器View,然后调节容器View的大小 无限轮播这里我使用的是一个第三方的插件react-na ...

  6. android TableLayOut画表格

    <TableRow android:layout_width="match_parent" android:layout_height="wrap_content& ...

  7. 20170915 linux系统管理培训

    进程管理 程序:通常为二进制程序放在存储媒介中(如光盘.硬盘.软盘.磁带等),以物理文件的形式存在: 进程:正在运行当中的程序,程序被触发后,执行者的权限与属性.程序的程序代码与所有数据等都会被加载到 ...

  8. python的第三方库

    python的第三方库 https://www.lfd.uci.edu/~gohlke/pythonlibs/

  9. SQL——查询一段时间内每天的数据,按天将数据封装进行封存

    DROP TABLE IF EXISTS `T_ROTA_RECORD`; CREATE TABLE `T_ROTA_RECORD` ( `id` ) NOT NULL AUTO_INCREMENT, ...

  10. vue中mixins的使用

    与vuex的区别 经过上面的例子之后,他们之间的区别应该很明显了哈~ vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随 ...