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 ActionBarSherlock使用说明
源代码地址:https://github.com/JakeWharton/ActionBarSherlock 1.添加项目依赖包 2.修改AndroidManifest.xml中的主题(或者继承该主题 ...
- python 对时间操作
from datetime import datetime,timedelta 'date_test':fields.function(_datetime_all,type='datetime', ...
- [Oracle][Metadata]如何查找与某一个功能相关的数据字典名
当Oracel的一个新功能出来的时候,我们可能不知道所有与此功能关联的数据字典名称,那么如何才能得到这些 meta data 的 meta data 呢? 可以通过 dicitonary 来查看: 例 ...
- SqlServer 案例:已有汽车每日行驶里程数据,计算其每日增量
需求说明 某公司某项业务,需要获得用户每日行车里程数.已知能获得该车每日提交的总里程数,如何通过 T-SQL 来获得其每日增量里程? 解决方案 首选需要对数据进行编号,利用开窗函数 OVER() 实现 ...
- 【已解决】HeidiSQL连接(登录)MySQL数据库报错10061问题
解决方法: 打开cmd->输入命令services.msc 然后打开即可解决.
- Qt Creator 中,如何更改h,cpp,ui的文件并不让ui失效
这个星期在使用qt,碰到一个很蛋疼的问题:创建对话框的时候,不小心输错了名字.而且是在很迟才发现的.这个时候对话框都已经布局差不多了,为了改名字,碰到更蛋疼的问题,改了名字后就无法使用转到槽的功能了. ...
- [ERROR] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!
测试mysqld启动mysql server的时候,报如下错误: 2015-12-17 00:46:02 10785 [ERROR] Fatal error: Please read "Se ...
- oracle系统化学习笔记
CentOS 4.x上安装Oracle 9i(3讲) oracle9i非常成熟,刚学主要是学9i比较经典 学会安装9i具有现实意义,先学完9i再学11g等比较好 1.安装centos 2.安装orac ...
- main函数是必须的吗
研究实验4 研究过程: 问题引出:C语言编程非得用主函数main吗,不用是否可以? 对此问题进行研究,用tc.exe书写代码如下: 图1 没有main函数的c程序 对其进行编译,链接发现,编译阶段可 ...
- java中for循环的几种方式
比如定义一个数组int a[]={1, 2, 3, 4},下面我们罗列一下遍历这个数组的方法 1 for(;;) 这也是最常用的方法,不多做解释.代码如下 int a[] = {1, 2, 3, 4} ...