树链剖分——NOI2015
8说了上代码
给定一棵树,两种操作
a x:x->root路径上的点权值置1
b x: 把x的子树所有结点权值置0
树上的区间更新操作,显然是要维护dfs
第一个操作暴力显然是t,用树剖把复杂度降到log^2n级
线段树上:区间置1|0
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
struct Edge{int to,nxt;}edge[maxn<<];
int head[maxn],tot,n,q; int f[maxn],son[maxn],size[maxn],d[maxn];
void dfs1(int x,int pre,int deep){
size[x]=;d[x]=deep;f[x]=pre;
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y==pre)continue;
dfs1(y,x,deep+);
size[x]+=size[y];
if(size[y]>size[son[x]])son[x]=y;
}
}
int top[maxn],id[maxn],rk[maxn],cnt;
void dfs2(int x,int tp){
top[x]=tp;id[x]=++cnt;rk[cnt]=x;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y!=son[x] && y!=f[x])dfs2(y,y);
}
} #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[maxn<<],lazy[maxn<<];
void pushup(int rt){sum[rt]=sum[rt<<]+sum[rt<<|];}
void pushdown(int l,int r,int rt){
if(lazy[rt]<)return;
if(lazy[rt]==){
lazy[rt<<]=lazy[rt<<|]=;
sum[rt<<]=sum[rt<<|]=;
lazy[rt]=-;
}
if(lazy[rt]==){
int m=l+r>>;
lazy[rt<<]=lazy[rt<<|]=;
sum[rt<<]=m-l+;sum[rt<<|]=r-m;
lazy[rt]=-;
}
}
void set0(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){lazy[rt]=;sum[rt]=;return;}
pushdown(l,r,rt);
int m=l+r>>;
if(L<=m)set0(L,R,lson);
if(R>m)set0(L,R,rson);
pushup(rt);
}
void set1(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){lazy[rt]=;sum[rt]=r-l+;return;}
pushdown(l,r,rt);
int m=l+r>>;
if(L<=m)set1(L,R,lson);
if(R>m)set1(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l &&R >=r)return sum[rt];
int m=l+r>>,res=;
pushdown(l,r,rt);
if(L<=m)res+=query(L,R,lson);
if(R>m)res+=query(L,R,rson);
return res;
} void Set1(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
set1(id[top[x]],id[x],,n,);
x=f[top[x]];
}
if(id[x]>id[y])swap(x,y);
set1(id[x],id[y],,n,);
}
int Query(int x,int y){
int res=;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res+=query(id[top[x]],id[x],,n,);
x=f[top[x]];
}
if(id[x]>id[y])swap(x,y);
return res+query(id[x],id[y],,n,);
} void init(){
memset(head,-,sizeof head);
memset(lazy,-,sizeof lazy);
tot=;
}
void addedge(int u,int v){
edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
} int main(){
init();
cin>>n;
for(int u=;u<=n;u++){
int fa;scanf("%d",&fa);fa++;
addedge(fa,u);addedge(u,fa);
}
cnt=;dfs1(,,);dfs2(,); cin>>q;char op[];int x;
while(q--){
scanf("%s %d",op,&x);++x;
if(op[]=='i'){
int tmp=Query(x,);
cout<<d[x]-tmp<<'\n';
Set1(x,);
}
if(op[]=='u'){
cout<<query(id[x],id[x]+size[x]-,,n,)<<'\n';
set0(id[x],id[x]+size[x]-,,n,);
}
}
}
树链剖分——NOI2015的更多相关文章
- BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4196 给出一棵树,树上点权为0或1.u权值为1的条件是从根节点到u路径上的所有点权值都为1.u ...
- Bzoj 4196: [Noi2015]软件包管理器 树链剖分
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 721 Solved: 419[Submit][Statu ...
- 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)
[BZOJ4196][NOI2015]软件包管理器 题面 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你 ...
- BZOJ_4196_[Noi2015]软件包管理器_树链剖分
BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- 【BZOJ4196】[Noi2015]软件包管理器 树链剖分
[Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树
软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...
- 【NOI2015】 软件包管理器 - 树链剖分
noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...
随机推荐
- [ffmpeg] 滤波格式协商
ffmpeg的中滤波器是以帧为原料来进行滤波的,那么自然地就会对帧的格式有所要求,可以说如果滤波器不知道帧的格式,就无法对帧进行处理.在进行视频滤波时,滤波格式指的是视频的像素格式:在进行音频滤波时, ...
- SQL Server数据库中表的查
DataSet 数据集 DataAdapter 数据适配器,DataSet对象与实际数据源之间的桥梁,自动开闭数据库连接,省略Open.Close.填充数据集,需要用到Fill方法. using Sy ...
- 我眼中的Adaboost
步骤: def buildStump(dataArr,classLabels,D): 1.循环取出数据集中的一个特征(一列)输入 (for:) 2.循环调整阀值threshVal (for:) 3, ...
- 理解依赖注入,laravel IoC容器
在看laravel文档的时候,有一个服务容器(IoC)的概念.它是这样介绍的:Laravel 服务容器是一个用于管理类依赖和执行依赖注入的强大工具.依赖注入听上去很花哨,其实质是通过构造函数或者某些情 ...
- getopt()函数 命令解析
今天做计算机系统结构实验时学习到一个非常方便的命令解析函数getopt(),简单做个笔记,方便日后复习. 头文件:#include<unistd.h> 函数原型:int getopt(in ...
- C++回顾day03---<string字符串操作>
一:string优点 相比于char*的字符串,C++标准程序库中的string类不必担心内存是否足够.字符串长度等等 而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下的需要. 二:str ...
- cocos2d-x入门学习笔记——Hello world分析
Hello world分析 1. “resource”文件夹 用于存放图片.音频和配置等资源文件.为了方便管理,可以创建在其中创建子文件夹.Cocos2d-x为我们屏蔽了不同平台对于文件路径的定义. ...
- Ubuntu18.04应用程序安装集锦
整理网上的资源: Python Web开发工具箱 ubuntu美化及超NB的zsh配置 api文档查询工具:zeal,dash(收费)
- Flask 之东方不败一
1,flask的初始 flask是Python的一个轻量级的web框架,相当于django而言. 知识点Python 三大主流web框架的对比 1.Django 主要特点是大而全,集成了很多组件,例如 ...
- python整数与IP地址转换
python整数与IP地址转换 [转] 我们有时会将一个整数与IP地址进行互换,用python代码实现很简单将一个整数如2000000,变为一个IP地址的方式 >>> import ...