抄自:http://blog.csdn.net/coldef/article/details/61412577

当时看了就不会,看了别人的题解不懂怎么维护,最后抄了个代码.......

给定一棵n个点的树,每个点有颜色。m次询问,每次询问一个节点子树中深度和这个点深度之差<=d的点的颜色数量。多组数据,每组n,m<=10^5,总共小于500000

题解:如果不考虑深度,我们可以把相同颜色的节点按照dfs序排序,然后相邻节点在lca处-1,这样求子树和就可以求出答案了。考虑深度,我们就用主席树以深度为时间戳来维护呗。感觉看了原作者的代码学到了很多,原作者用set来维护相邻的相同颜色的节点真的妙。

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<set>
#include<algorithm>
#define mp(x,y) make_pair
#define pa pair<int,int>
#define itr set<pair<int,int> >::iterator
#define MAXN 100000
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
} int n,m,cnt,cc,dfn,head[MAXN+],p[MAXN+];
int fa[MAXN+][],rt[MAXN+],dep[MAXN+],nl[MAXN+],nr[MAXN+],col[MAXN+];
struct TREE{
int l,r,x,lt,rt;
}T[];
vector<int> v[MAXN+];
set<pa > ev[MAXN+];
struct edge{
int to,next;
}e[*MAXN+];
inline void ins(int f,int t){e[++cc].next=head[f];head[f]=cc;e[cc].to=t;}
bool cmp(int x,int y){return nl[x]<nl[y];}
bool cmp2(int x,int y){return dep[x]<dep[y];} void dfs(int x,int d)
{
dep[x]=d;nl[x]=++dfn;
for(int i=head[x];i;i=e[i].next)dfs(e[i].to,d+);
nr[x]=dfn;
} int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);int th=dep[x]-dep[y];
for(int i=;th;th>>=,++i)if(th&)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][];
} void renew(int x0,int&x,int k,int ad,int l,int r)
{
// cout<<"renew"<<x0<<" "<<x<<" "<<k<<" "<<ad<<" "<<l<<" "<<r<<endl;
x=++cnt;T[x].lt=T[x0].lt;T[x].rt=T[x0].rt;
T[x].l=l;T[x].r=r;T[x].x=T[x0].x+ad;
if(l==r)return;int mid=(l+r)>>;
if(k<=mid)renew(T[x0].lt,T[x].lt,k,ad,l,mid);
else renew(T[x0].rt,T[x].rt,k,ad,mid+,r);
} int query(int k,int l,int r)
{
//cout<<"query"<<k<<" "<<l<<" "<<r<<endl;
if(!k)return ;
if(T[k].l==l&&T[k].r==r)return T[k].x;
int mid=(T[k].l+T[k].r)>>;
if(r<=mid)return query(T[k].lt,l,r);
else if(l>mid) return query(T[k].rt,l,r);
else return query(T[k].lt,l,mid)+query(T[k].rt,mid+,r);
} int main()
{
int T=read();
for(int i=;i<=T;i++)
{
cnt=cc=dfn=;for(int i=;i<=n;i++)v[i].clear();
memset(head,,sizeof(head));memset(rt,,sizeof(rt));n=read();m=read();
for(int i=;i<=n;i++){col[i]=read();}
for(int i=;i<=n;i++){fa[i][]=read();ins(fa[i][],i);}
dfs(,);
for(int i=;i<;i++)for(int j=;j<=n;j++)
fa[j][i]=fa[fa[j][i-]][i-];
for(int i=;i<=n;i++)p[i]=i;sort(p+,p+n+,cmp2);
for(int i=;i<=n;i++)
{
int x=p[i],y=p[i-];
renew(rt[dep[y]],rt[dep[x]],nl[x],,,n);
if(ev[col[x]].empty()){ev[col[x]].insert(pa(nl[x],x));continue;}
ev[col[x]].insert(pa(nl[x],x));
itr it=ev[col[x]].find(pa(nl[x],x));
itr a=--it;it=ev[col[x]].find(pa(nl[x],x));itr b=++it;
if(a!=ev[col[x]].end()&&b!=ev[col[x]].end())renew(rt[dep[x]],rt[dep[x]],nl[lca(a->second,b->second)],,,n);
if(a!=ev[col[x]].end())renew(rt[dep[x]],rt[dep[x]],nl[lca(x,a->second)],-,,n);
if(b!=ev[col[x]].end())renew(rt[dep[x]],rt[dep[x]],nl[lca(x,b->second)],-,,n);
}
int last=;
for(int i=;i<=n;i++)ev[i].clear();
for(int i=;i<=m;i++)
{
int u=read()^last,v=read()^last;
last=query(rt[min(dep[p[n]],dep[u]+v)],nl[u],nr[u]);
printf("%d\n",last);
}
}
return ;
}

我好菜啊都不会。

[bzoj省选十连测推广赛2]T2七彩树的更多相关文章

  1. [BZOJ]2017省队十连测推广赛1 T2.七彩树

    题目大意:给你一棵n个点的树,每个点有颜色,m次询问,每次询问一个点x的子树内深度不超过depth[x]+d的节点的颜色数量,强制在线.(n,m<=100000,多组数据,保证n,m总和不超过5 ...

  2. bzoj省选十连测推广赛

    A.普通计算姬 题意:给丁一棵树,每个点有一个权值,用sum(x)表示以x为根的子树的权值和,要求支持两种操作: 1 u v  :修改点u的权值为v. 2 l  r   :  求∑sum[i] l&l ...

  3. [BZOJ]2017省队十连测推广赛1

    听学长说有比赛就随便打一打. A.普通计算姬 题目大意:给出一棵带权树,支持一下两种操作:1.修改一个点的权值:2.给出l,r,询问以点l为根的子树和.点l+1为根的子树和.点l+2为根的子树和--点 ...

  4. 【省选十连测之九】【DP】【组合计数去重】【欧拉函数】基本题

    目录 题意: 输入格式: 输出格式: 数据范围: 思路: 嵌套题的转移 基本题的转移 Part1 Part2 Part3 代码 题意: 这是一个关于括号组合的题. 首先定义一道题是由'(',')',' ...

  5. 【省选十连测之一】【线段树】【最小生成树之Kruskal】公路建设

    目录 题意 输入格式 输出格式 数据范围 思路 代码 题意 有n个点,m条双向道路,其中第条公路的两个端点是u[i],v[i],费用是c[i]. 现在给出q个询问,每次给定一个L和一个R,要求你只能够 ...

  6. 【正睿oi省选十连测】第一场

    四小时写了两个暴力??自闭 [原来这就是神仙们的分量Orz rank 56/75 可以说是无比垃圾了 下周目标:进步十名?[大雾 T1 题意:有n个点的图 点有点权Ai 也有点权Bi = A_1 + ...

  7. bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树

    [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 93  Solved: 53[Submit][Status][ ...

  8. bzoj 5216: [Lydsy2017省队十连测]公路建设

    5216: [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 66  Solved: 37[Submit][St ...

  9. ZROI2019 提高十连测

    额 掰手指头一数 特么又是第三年十连测了= = 2017一场没打 那时候好像一场比赛也就100人左右 2018前几场还都好好补了 后来开始放飞自我了 这时候一场有150人还多了 2019想让今年的No ...

随机推荐

  1. js日常积累

    1.数组转字符串 str.join(',') 2.字符串转数组 arr.split(',') 3.数组排序 function sorb(a,b){return a-b;}; arr.sort(sorb ...

  2. aix 6.1系统怎么安装?这里有详细图文教程

    今年六月,我们公司出现了一次非常严重的数据丢失的事故.生产服务器崩溃导致所有的业务都陷于停滞,而且由于涉及到公司机密又无法贸然到数据恢复公司进行恢复,可是自己又无法解决.权衡利弊还是决定找一家有保密资 ...

  3. Vue 2.0基础语法:系统指令

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. Vue初体验 新建一个空的项目,引入vue.js文件.写如下代码: &l ...

  4. 在网络编程中的io流小问题

    在客户端和服务端调用io流进行传输数据的过程中,当将数据write到outputstream中,需要及时刷新,否则会发生io阻塞. 在输入数据的时候,最好选用BufferedReader,因为read ...

  5. 阿里云CentOS部署小笔记

    快毕业了,我用近两周的时间完成了一个nodeJs+Vue-Cli+Mysql的毕业设计,到了部署的时候了. 然而,博主使用Linux的经验有限得很,所以只能自己慢慢地填坑了. 一.准备工作 1)阿里云 ...

  6. Mego开发文档 - 基本保存操作

    基本保存操作 在Mego中没有更改跟踪,也就是说所有的新增.更新及删除都需要开发者自行判断.Mego会最为实际的将各个数据操作提交给数据库并执行. 添加数据 using (var db = new O ...

  7. 租户、租户管理员、部门管理员和开发者在APIGW中的角色

    一.参与者 1.vdcId:租户 2.运营管理员 operator: 一种角色 创建开发商 审批外置服务,如:hadoop集群 审批内置服务,如:<API使用申请> 3.租户管理员     ...

  8. eclipse开发Groovy代码,与java集成,maven打包编译

    今天尝试了一下在eclipse里面写Groovy代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给eclipse安装一下Groovy的插件,插件地址:https://gith ...

  9. Pyhon之Django中的Form组件

    Pyhon之Django中的Form组件   新手上路 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面 ...

  10. Django 学生管理系统

    1. 一对一 班级  模态增加 编辑 def classes(request): data = sqlheper.get_list("select cid,title from class& ...