BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述
输入
输出
输出一个正整数,表示结果
样例输入
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3
样例输出
2
2
1
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int x,y;
int tot;
int num;
char ch[2];
int f[100010];
int s[100010];
int d[100010];
int t[100010];
int to[200010];
int mx[800010];
int next[200010];
int head[100010];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x)
{
s[x]=++num;
d[x]=d[f[x]]+1;
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x])
{
f[to[i]]=x;
dfs(to[i]);
}
}
t[x]=num;
}
int cmp(int x,int y)
{
if(d[x]>d[y])
{
return x;
}
else
{
return y;
}
}
void change(int rt,int l,int r,int L,int R,int k)
{
if(L<=l&&r<=R)
{
mx[rt]=cmp(mx[rt],k);
return ;
}
int mid=(l+r)>>1;
if(L<=mid)
{
change(rt<<1,l,mid,L,R,k);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,k);
}
}
int query(int rt,int l,int r,int k)
{
if(l==r)
{
return mx[rt];
}
int mid=(l+r)>>1;
int res=mx[rt];
if(k<=mid)
{
return cmp(res,query(rt<<1,l,mid,k));
}
else
{
return cmp(res,query(rt<<1|1,mid+1,r,k));
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1);
change(1,1,n,1,n,1);
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
scanf("%d",&x);
if(ch[0]=='C')
{
change(1,1,n,s[x],t[x],x);
}
else
{
printf("%d\n",query(1,1,n,s[x]));
}
}
}
树链剖分+线段树
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int x,y;
int tot;
int num;
char ch[2];
int f[100010];
int s[100010];
int d[100010];
int q[100010];
int to[200010];
int mx[800010];
int son[100010];
int top[100010];
int size[100010];
int next[200010];
int head[100010];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x)
{
d[x]=d[f[x]]+1;
size[x]=1;
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x])
{
f[to[i]]=x;
dfs(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]])
{
son[x]=to[i];
}
}
}
}
void dfs2(int x,int tp)
{
s[x]=++num;
q[num]=x;
top[x]=tp;
if(son[x])
{
dfs2(son[x],tp);
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
int cmp(int x,int y)
{
if(d[x]>d[y])
{
return x;
}
else
{
return y;
}
}
void pushup(int rt)
{
mx[rt]=cmp(mx[rt<<1],mx[rt<<1|1]);
}
void change(int rt,int l,int r,int k,int v)
{
if(l==r)
{
mx[rt]=v;
return ;
}
int mid=(l+r)>>1;
if(k<=mid)
{
change(rt<<1,l,mid,k,v);
}
else
{
change(rt<<1|1,mid+1,r,k,v);
}
pushup(rt);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return mx[rt];
}
int mid=(l+r)>>1;
if(L>mid)
{
return query(rt<<1|1,mid+1,r,L,R);
}
if(R<=mid)
{
return query(rt<<1,l,mid,L,R);
}
else
{
return cmp(query(rt<<1,l,mid,L,R),query(rt<<1|1,mid+1,r,L,R));
}
}
int ask(int x)
{
int res;
while(top[x]!=1)
{
res=query(1,1,n,s[top[x]],s[x]);
if(res!=0)
{
return res;
}
x=f[top[x]];
}
res=query(1,1,n,1,s[x]);
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1);
dfs2(1,1);
change(1,1,n,1,1);
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
scanf("%d",&x);
if(ch[0]=='C')
{
change(1,1,n,s[x],x);
}
else
{
printf("%d\n",ask(x));
}
}
}
BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树的更多相关文章
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set
[题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...
随机推荐
- Android学习之Button按钮在程序运行时全部变大写的处理
问题: 在layout布局文件中,我们命名的按钮名称是“button1”,程序运行过后,在app上显示出来的是“BUTTON1”,先看源代码和效果: 按钮源代码: 运行效果: 解决办法: 方法一: 在 ...
- Linux下对inode和块的理解
基本概念 首先讲下inode和块的基本概念.在Linux系统中,文件由元数据和数据块组成.数据块就是多个连续性的扇区(sector),扇区是文件存储的最小单位(每个512字节).块(block)的大小 ...
- wifidog源码分析 - wifidog原理
wifidog是一个用于配合认证服务器实现无线网页认证功能的程序,常见的情景就是使用于公共场合的无线wifi接入点,首先移动设备会连接公共wifi接入点,之后会弹出网页要求输入用户名密码,认证过后才能 ...
- NOI Day1线上同步赛梦游记
Preface 第一次体验NOI,虽然不是正式选手,但是打打同步赛还是挺涨姿势的,也算是体验了一把. Day1很爆炸,一方面是NOI题目的难度高于自身的水平,另一方面也出现了比较大的失误,T1一个数组 ...
- C#_Math函数总结
Math.abs() 计算绝对值. Math.acos() 计算反余弦值. Math.asin() 计算反正弦值. Math.atan() 计算反正切值. Math.atan2() 计算从x 坐标轴到 ...
- nginx负载均衡(5种方式)、rewrite重写规则及多server反代配置梳理
Nginx除了可以用作web服务器外,他还可以用来做高性能的反向代理服务器,它能提供稳定高效的负载均衡解决方案.nginx可以用轮询.IP哈希.URL哈希等方式调度后端服务器,同时也能提供健康检查功能 ...
- mysql操作命令梳理(4)-中文乱码问题
在平时的mysql运维操作中,经常会碰到插入中文字段后出现乱码的情况,产生中文乱码的原因一般有:1)mysql的编码格式不对,是latin1编码.强烈推荐将mysql下的编码格式都改为utf8,因为它 ...
- css3 动画效果实现
前沿 在工作中,经常有一些需要切换的交互样式.如果直接在两种状态之间切换,就显得有点生硬.加上一些动画效果就会好很多. 示例1:点击的三角切换 实现过程 第一步实现这个三角形 用的svg 的多边形画法 ...
- D. Boxes Packing
链接 [http://codeforces.com/contest/1066/problem/D] 题意 题目大意 n个物品m个篮子每个篮子容量为k 每个物品重量为a[i] 问能装多少物品 这个人是强 ...
- Visual Studio2015安装过程以及单元测试
安装环境: 安装版本: Visual Studio2015 安装过程: 因为我是在第一次老师安排的作业的时候感觉VC++6.0不如VS方便所以才装的Visual Studio2015,又安装了点插件, ...