思路:

因为有深度的限制,并且我们是在线段树上维护权值,所以我们把点按照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的更多相关文章

  1. BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树+dfs序

    BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道 ...

  2. 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治

    正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...

  3. [BZOJ 4771]七彩树(可持久化线段树+树上差分)

    [BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...

  4. bzoj 4539 [Hnoi2016]树——主席树+倍增

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4539 明明就是把每次复制的一个子树当作一个点,这样能连出一个树的结构,自己竟然都没想到.思维 ...

  5. bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】

    算是板子,把值离散化,每个点到跟上做主席树,然后查询的时候主席树上用u+v-lca-fa[lca]的值二分 #include<iostream> #include<cstdio> ...

  6. BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)

    Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...

  7. BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增

    建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...

  8. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

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

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

随机推荐

  1. Eclipse之调试代码和返回

    编写代码时,经常会遇到各种莫名其妙的问题,为了检测程序是哪里出现问题,我们通过断点调试来判断哪一步出错 一.断点 在需要断点的地方,在左侧双击鼠标设置断点,可设置多个 去掉断点:在断点上双击一下,没有 ...

  2. AS3.0+PHP写入mySQL

    php中$_POST变量是一个数组,用于收集来自method="post"的值,内容是有HTTP POST方法发送的变量名称和值. 从带有POST方法的表单发送的信息,对任何人都是 ...

  3. 面试回答问题要防范hr的陷阱

    面试技巧是大众化的,比较实在.在经历的各种面试中,最不容易防范的面试就是“拉呱”(山东方言,聊天的意思),这样子自己容易放松警惕. 看看下面的,就知道应该怎么应对这些“滑头”的HR! 1.我们为什么要 ...

  4. ssl_protocols和ssl_ciphers应该怎么配置

    http://wiki.nginx.org/HttpSslModule#ssl_ciphers 推荐配置: A) 在Apache 的 SSL 配置中禁用 SSLv3 和 SSLv3SSLProtoco ...

  5. MQTTnet 的Asp.Net Core 认证事件的扩展

    MQTTnet 的数据接收 连接 等事件都很丰富, 唯独客户端连接验证不能依赖注入也不能很舒服的使用事件的方式, 因此MQTTnet.AspNetCoreEx 就出现了. 示例如下:在  public ...

  6. js数组操作find查找特定值结合es6特性

    js数组操作find查找特定值结合es6特性

  7. JavaScript、Dom和jQuery

    var obj=document.getElementById('t1') obj.innerText obj.innerHTML 1.javascript 插入代码如下: <script ty ...

  8. 【剑指Offer】31、从1到n整数中1出现的次数

      题目描述:   求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他 ...

  9. 26.bulk批量操作

    主要知识点 1.bulk语法 2.bulk使用时的注意事项 3.bulk size 对es性能的影响     一.bulk语法 每一个操作要两个json串(delete操作除外),每个json串占一行 ...

  10. 6.在idea中链接数据库

    1.打开数据库配置的窗口 File - view  - Tool Windows - Database 2.打开mysql的数据库链接模板 Database - + - Data Source - M ...