Boss Bo (主席树)
主要想法:假设给你足够时间,那么就可以对每个点建议一颗线段树来查询了,但是需要将点全部按照某个特定的序列存进线段树,如代码是以树的深搜顺序作为指定顺序,这样以来我们既可以将数据查询分成诺干个区间进行查询了,减少了大量查询。那么这样你都知道了,其实只需要利用主席树将每个点的情况都存进去主席树里面,因为对于相邻的点来说有着太多的重复情况了,所以我们可以利用这个数据结构来优化时间。
#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 (主席树)的更多相关文章
- HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 主席树:HDU 4417 Super Mario
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- bzoj 1901 主席树+树状数组
修改+查询第k小值 单纯主席树修改会打乱所有,所以再套一个树状数组维护前缀和使得修改,查询都是log 对了,bzoj上不需要读入组数,蜜汁re.. #include<cstdio> #in ...
- Super Mario HDU - 4417 (主席树)
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...
- hdu 4417 Super Mario 树状数组||主席树
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Prob ...
- Super Mario(主席树)
Super Mario Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded ...
- hdu4417 主席树求区间小于等于K
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 Problem Description Mario is world-famous plum ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
随机推荐
- Servlet (二)ServletContext
package cn.sasa.serv; import java.io.IOException; import javax.servlet.ServletContext; import javax. ...
- winform接收全局的快捷键
public class NativeWIN32 { public NativeWIN32() { } /* ------- using WIN32 Windows API in a C# appli ...
- C语言课堂题集
1.输入一个整数,然后将其数字位置颠倒. int c,d=0,e; scanf("%d",&c); while (c!=0) { e=c%10; d=d*10+e; c/= ...
- 让网站不去请求favicon.ico图标
让网站不去请求favicon.ico图标 favicon.ico 图标用于收藏夹图标和浏览器标签上的显示,如果不设置,浏览器会请求网站根目录的这个图标,如果网站根目录也没有这图标会产生 404.出于优 ...
- 在WCF服务端的web.config中增加如下设置,具体的错误会记录在.svclog文件中
<system.diagnostics> <sources> <source name="System.ServiceModel" switchVal ...
- python 字符串、列表和元祖之间的切换
>>> s=['http','://','www','baidu','.com'] >>> url=''.join(s) >>> url 'htt ...
- K-means &K-medoids 聚类
k-平均值算法对孤立点很敏感!因为具有特别大的值的对象可能显著地影响数据的分布. k-中心点(k-Medoids): 不采用簇中对象的平均值作为参照点, 而是选用簇中位置最中心的对象, 即中心点(me ...
- PHP 类名::class含义
自 PHP 5.5 起,关键词 class 也可用于类名的解析. 使用 ClassName::class 可以获取一个字符串,包含了类 ClassName 的完全限定名称.这对使用了命名空间的类尤其有 ...
- PHP面试准备
框架:Laravel,Yii,Tp (1)纵向不同版本及框架本身特性 (2)横向对比,不同框架的优缺点 面向对象编程: (1)面向对象的基本特征:封装,继承,多态 (2)设计模式:单例模式,工厂模式, ...
- Kotlin 范型约束
官方的示意及其简约,该说的一概没说 我在这里给大家一个完整的例子 //test.kt fun <T> cloneWhenGreater(list: List<T>, thres ...