BZOJ 4771 主席树+倍增+set
思路:
因为有深度的限制,并且我们是在线段树上维护权值,所以我们把点按照dep排序,然后一个一个修改...主席树的下标就是dfs序,子树的查询就是区间查询...
但是发现这样怎么去维护LCA呢...因为要求有序,所以我们可以用set来维护相同颜色的节点...如果把一个点加入集合之后这个点前驱为x,后继为y,那么我们去修正,把xy的LCA+1,然后x和当前点的LCA-1,当前点和y的LCA-1...
from neighthorn
//By SiriusRen
#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int n,m,cases,v[N],next[N],first[N],tot,fa[N][],dfn[N],cnt,root[N],lst[N],dep[N];
int tree[N*],lson[N*],rson[N*],xx,yy,ans;
struct Node{int x,deep,col;}node[N];
bool cmp(Node a,Node b){return a.deep<b.deep;}
bool cmp2(Node a,Node b){return a.x<b.x;}
struct Cmp{bool operator()(Node a,Node b){return dfn[a.x]<dfn[b.x];}};
set<Node,Cmp>s[N];set<Node,Cmp>::iterator it,it2,it3;
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void dfs(int x){
dfn[x]=++cnt;
for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x][])
dep[v[i]]=node[v[i]].deep=node[x].deep+,dfs(v[i]);
lst[x]=cnt;
}
void insert(int l,int r,int &pos,int last,int num,int wei){
pos=++cnt,tree[pos]=tree[last]+wei;
if(l==r)return;
int mid=(l+r)>>;
if(mid<num)lson[pos]=lson[last],insert(mid+,r,rson[pos],rson[last],num,wei);
else rson[pos]=rson[last],insert(l,mid,lson[pos],lson[last],num,wei);
}
int query(int l,int r,int pos,int L,int R){
if(l>=L&&r<=R)return tree[pos];
int mid=(l+r)>>;
if(mid<L)return query(mid+,r,rson[pos],L,R);
else if(mid>=R)return query(l,mid,lson[pos],L,R);
else return query(l,mid,lson[pos],L,R)+query(mid+,r,rson[pos],L,R);
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=;~i;i--)if(dep[x]-(<<i)>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;~i;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
int main(){
scanf("%d",&cases);
while(cases--){
memset(first,-,sizeof(first)),ans=tot=cnt=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&node[i].col),node[i].x=i;
for(int i=;i<=n;i++)scanf("%d",&fa[i][]),add(fa[i][],i);
for(int j=;j<=;j++)for(int i=;i<=n;i++)fa[i][j]=fa[fa[i][j-]][j-];
dep[]=node[].deep=,dfs(),cnt=,sort(node+,node++n,cmp);
for(int i=;i<=n;i++){
int lst=node[i-].deep,now=node[i].deep;
insert(,n,root[now],root[lst],dfn[node[i].x],);
s[node[i].col].insert(node[i]),it=s[node[i].col].find(node[i]);it2=it,++it2;
if(s[node[i].col].size()>&&it!=s[node[i].col].begin()&&it2!=s[node[i].col].end())
it2=it,it2--,it3=it,it3++,insert(,n,root[now],root[now],dfn[lca((*it2).x,(*it3).x)],);
if(it!=s[node[i].col].begin())it2=it,it2--,insert(,n,root[now],root[now],dfn[lca((*it2).x,(*it).x)],-);
it2=it,++it2;
if(it2!=s[node[i].col].end())insert(,n,root[now],root[now],dfn[lca((*it2).x,(*it).x)],-);
}
while(m--){
scanf("%d%d",&xx,&yy),xx^=ans,yy^=ans;
printf("%d\n",ans=query(,n,root[min(dep[xx]+yy,node[n].deep)],dfn[xx],lst[xx]));
}
for(int i=;i<=n;i++)s[i].clear(),root[i]=;
}
}
BZOJ 4771 主席树+倍增+set的更多相关文章
- BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树+dfs序
BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道 ...
- 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治
正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- bzoj 4539 [Hnoi2016]树——主席树+倍增
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4539 明明就是把每次复制的一个子树当作一个点,这样能连出一个树的结构,自己竟然都没想到.思维 ...
- bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】
算是板子,把值离散化,每个点到跟上做主席树,然后查询的时候主席树上用u+v-lca-fa[lca]的值二分 #include<iostream> #include<cstdio> ...
- BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)
Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- bzoj 1901 主席树+树状数组
修改+查询第k小值 单纯主席树修改会打乱所有,所以再套一个树状数组维护前缀和使得修改,查询都是log 对了,bzoj上不需要读入组数,蜜汁re.. #include<cstdio> #in ...
随机推荐
- EnforceLearning-被动强化学习
前言: 画图挺好:深度学习进阶之路-从迁移学习到强化学习 专家系统给出了知识节点和规则,使用粒度描述准确性,依靠分解粒度解决矛盾,并反馈知识和推理规则更新.专家系统与机器学习有本质区别,但从机器学习的 ...
- 多开 MFC线程
序言:我才编程几年啊!就要处理多线程.对于只写函数的我,这难度简直了!不过MFC的多线程,貌似比较简单,还能处理的了. (1).开MFC多个线程 在视频采集的过程中,如果不使用媒体计数器,会造成主线程 ...
- Swift Method Dispatching — a summary of my talk at Swift Warsaw
Swift Method Dispatching When announcing Swift, Apple described it as being much faster than Objecti ...
- 移动端出现弹出层body滚动
$("#box").on("click",function(e){ e.stopPropagation(); e.preventDefault(); $(&qu ...
- 【剑指Offer】47、求1+2+3+4+···+n
题目描述: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 解题思路: 本题本身没有太多 ...
- USACO 4.1 Fence Loops
Fence Loops The fences that surround Farmer Brown's collection of pastures have gotten out of contro ...
- CSS学习笔记之CSS3新特性
目录 1.边框 2.背景 3.文本 4.字体 5.转换 6.过渡 7.动画 8.多列 9.自定义尺寸 CSS 用于控制网页的样式和布局,而 CSS3 是最新的 CSS 标准,这篇文章将着重介绍 CSS ...
- 解决@vue/cli 创建项目是安装chromedriver时失败的问题
最近在使用新版vue的命令行工具创建项目时,安装chromedriver老是失败,导致后面的步骤也没有进行.网上搜索了一下,全是使用 工作中常见问题汇总及解决方案 npm install chrome ...
- Golang - 爬虫案例实践
目录 Golang - 爬虫案例实践 1. 爬虫步骤 2. 正则表达式 3. 并发爬取美图 Golang - 爬虫案例实践 1. 爬虫步骤 明确目标(确定在哪个网址搜索) 爬(爬下数据) 取(去掉没用 ...
- Git 基础教程 之 从远程库克隆
③ 克隆一个本地仓库 a, 在合适的地方,在Git Bash下执行命令: git clone git@github.com:hardy9sap/gittutorial.git