[bzoj省选十连测推广赛2]T2七彩树
抄自: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七彩树的更多相关文章
- [BZOJ]2017省队十连测推广赛1 T2.七彩树
题目大意:给你一棵n个点的树,每个点有颜色,m次询问,每次询问一个点x的子树内深度不超过depth[x]+d的节点的颜色数量,强制在线.(n,m<=100000,多组数据,保证n,m总和不超过5 ...
- bzoj省选十连测推广赛
A.普通计算姬 题意:给丁一棵树,每个点有一个权值,用sum(x)表示以x为根的子树的权值和,要求支持两种操作: 1 u v :修改点u的权值为v. 2 l r : 求∑sum[i] l&l ...
- [BZOJ]2017省队十连测推广赛1
听学长说有比赛就随便打一打. A.普通计算姬 题目大意:给出一棵带权树,支持一下两种操作:1.修改一个点的权值:2.给出l,r,询问以点l为根的子树和.点l+1为根的子树和.点l+2为根的子树和--点 ...
- 【省选十连测之九】【DP】【组合计数去重】【欧拉函数】基本题
目录 题意: 输入格式: 输出格式: 数据范围: 思路: 嵌套题的转移 基本题的转移 Part1 Part2 Part3 代码 题意: 这是一个关于括号组合的题. 首先定义一道题是由'(',')',' ...
- 【省选十连测之一】【线段树】【最小生成树之Kruskal】公路建设
目录 题意 输入格式 输出格式 数据范围 思路 代码 题意 有n个点,m条双向道路,其中第条公路的两个端点是u[i],v[i],费用是c[i]. 现在给出q个询问,每次给定一个L和一个R,要求你只能够 ...
- 【正睿oi省选十连测】第一场
四小时写了两个暴力??自闭 [原来这就是神仙们的分量Orz rank 56/75 可以说是无比垃圾了 下周目标:进步十名?[大雾 T1 题意:有n个点的图 点有点权Ai 也有点权Bi = A_1 + ...
- bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树
[Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 93 Solved: 53[Submit][Status][ ...
- bzoj 5216: [Lydsy2017省队十连测]公路建设
5216: [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 66 Solved: 37[Submit][St ...
- ZROI2019 提高十连测
额 掰手指头一数 特么又是第三年十连测了= = 2017一场没打 那时候好像一场比赛也就100人左右 2018前几场还都好好补了 后来开始放飞自我了 这时候一场有150人还多了 2019想让今年的No ...
随机推荐
- Huginn实现自动通过slack推送豆瓣高分电影
博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml 原文链接:https://blog.wang ...
- 【Learning】 多项式的相关计算
约定的记号 对于一个多项式\(A(x)\),若其最高次系数不为零的项是\(x^k\),则该多项式的次数为\(k\). 记为\(deg(A)=k\). 对于\(x\in(k,+ \infty)\),称\ ...
- node框架express
见识到原生nodeJs服务器的恶心后,我们来用下简单好用的框架吧~ 服务器无非主要提供接口和静态文件读取,直接上代码: const express = require('express'); cons ...
- Nginx原理和配置总结
一:前言 Nginx是一款优秀的HTTP服务器和反向代理服务器,除却网上说的效率高之类的优点,个人的切身体会是Nginx配置确实简单而且还好理解,和redis差不多,比rabbitmq好理解太多了: ...
- Linux入门:vi 和 vim
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器. 本文介绍了vi (vim)的基本使用方法,但对于普通用户来说基本上够了! 转自:http://www.l ...
- 新概念英语(1-109)A Good Idea
Lesson 109 A good idea 好主意 Listen to the tape then answer this question. What does Jane have with he ...
- SpringBoot的重要特性
一.Web特性 Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及Sp ...
- maven快速下载jar镜像
<!--国内镜像--><mirror> <id>CN</id> <name>OSChina Central</name> ...
- C# 后台构造json数据
前后台传值一般情况下,都会用到json类型的数据,比较常见,但是每次用到的时候去网上找比较麻烦,所以自己记录一下,下次直接用. 构造的json串格式,如下: [{","name&q ...
- spring6——AOP的编程术语
面向切面编程作为一种编程思想,允许我们对程序的执行流程及执行结果动态的做出改变,以达到业务逻辑之间的分层管理或者是目标对象方法的增强,spring框架很好的实现了这种编程思想,让我们可以对主业务逻辑和 ...