树链剖分——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用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...
随机推荐
- Heap Partition ZOJ - 3963(贪心)
ZOJ - 3963 贪心做一下就好了 反正别用memset #include <iostream> #include <cstdio> #include <sstrea ...
- tcpdump常用参数说明及常见操作
tcpdump常用参数说明及常见操作 -a 将网络地址和广播地址转变成名字 -c 指定抓包的数量 -d 将匹配信息包的代码以人们能够理解的汇编格式给出 -dd 将匹配信息包的代码以c语言程序段的格式给 ...
- CF1157C1-Increasing Subsequence (easy version)题解
原题地址 题目大意:
- linux下编译visp库
#下载源码git clone "https://github.com/lagadic/visp.git"#work目录mkdir work#build目录mkdir build#c ...
- bzoj1814 Ural 1519 Formula 1(插头DP)
对插头DP的理解还不是很透彻. 先说一下肤浅的理解吧. 插头DP使用范围:指数级复杂度,且适用于解决网格图连通性问题,如哈密顿回路等问题.插头一般指每相邻2个网格的接口. 题目难度:一般不可做. 使用 ...
- C++:普通变量C++命名规则
C++提倡使用拥有一定意义的变量名,使程序代码更有阅读性,命名是必须使用的几种简单的C++命名规则: 命名时只能使用:字母字符.数字和下划线(_); 第一个字符不能是数字: 区分大小写(C++对大小写 ...
- POJ 3666 Making the Grade (动态规划)
Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...
- 帕斯卡(pascal)命名法:
帕斯卡(pascal)命名法: 与骆驼命名法类似.只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写 如:public void DisplayInfo(); string UserName; ...
- Python:Mac 下 MQTT 服务器 Mosquitto 的配置
我在Mac电脑上搭建时遇到了一些不同于网上大部分情况的问题,特此分享给可能也有遇到相同情况又找不到解决方法的人. 我的电脑系统:macOS Mojave 10.14.3. paho-mqtt 的安装 ...
- 11GR2 Oracle数据库的远程投毒VNCR方式修复
[环境介绍] 系统环境:Solaris + Oracle 11GR2 + 单机/RAC [背景描述] 基于集团数据库安全检查项,需要数据库的远程投毒漏洞进行修复. 根据Oracle官方提供的修复文 ...