Libre OJ 144、145 (DFS序)
部分参考自博客:https://blog.csdn.net/hpu2022/article/details/81910490
在许多问题中,由于树结构复杂通常会导致问题很棘手,因为其实非线性结构,操作起来也甚是费时。
例如:对于一棵树,含有n个节点,每个节点拥有相应的权值,我们进行很多个操作,比如可以修改某个节点的权值,查找以某个节点为根节点的子树和。
显然,对于这个问题,每次计算子树权值和时我们都要遍历一下各个节点,而如果我们可以用某种方式把它装化成线性结构,然后再用数组数组或者线段树去更新查询,这样不就可以更高效得多吗?
没错,这就有了我们DFS序,它的主要思路就是将树形结构转化成线性结构,用dfs遍历一遍这棵树,进入到x节点有一个in时间戳,递归退出时有一个out 时间戳,x节点的两个时间戳之间遍历到的点,就是根为x的子树的所有节点,他们的dfs进入时间戳是递增的。同时两个时间戳构成了一个区间,x节点在这段区间的最左端,这个区间就是一棵根节点为x的子树,对于区间的操作就是其他维护方式的应用了。
- int time = ;
- inline void dfs(int x, int fa) {
- in[x] = ++time; //进入的时间戳
- num[time] = x; //生成新的线性结构
- for(int i = ; i < G[x].size(); i++) {
- int cnt = G[x][i];
- if(cnt == fa) continue;
- dfs(cnt, x);
- }
- out[x] = time; //出去的时间戳
- }
in[x]表示映射的DFS预处理出的线性结构,也就是说x是原始节点,in[x]是x节点的新位置,num[t]表示第t个节点的编号,num[in[x]]表示的还是x。num是新序列,in表示是新序列的下标,in[x]~out[x]是x为根结点的子树,划分为一个区间。
Loj144 DFS序+树状数组单点更新区间查找
题目链接:https://loj.ac/problem/144
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- #define lson l,mid,rt<<1
- #define rson mid+1,r,rt<<1|1
- typedef long long ll;
- const ll maxn=1e6+;
- int n,q,m,r,tot,cnt;
- ll v[maxn],in[maxn],out[maxn],head[maxn],x,num[maxn],sum[maxn];
- struct node{
- int to,next;
- }edge[*maxn];
- void add(int u,int v){
- edge[tot].to=v;
- edge[tot].next=head[u];
- head[u]=tot++;
- }
- void dfs(int pos,int fa){
- num[++cnt]=pos;
- in[pos]=cnt;
- for(int i=head[pos];i!=-;i=edge[i].next){
- int v=edge[i].to;
- if(v!=fa) dfs(v,pos);
- }
- out[pos]=cnt;
- }
- int lowbit(int x){
- return x&(-x);
- }
- void update(int x,int y){
- while(x<=n){
- sum[x]+=y;
- x+=lowbit(x);
- }
- }
- ll ask(int x){
- ll res=;
- while(x){
- res+=sum[x];
- x-=lowbit(x);
- }
- return res;
- }
- int main(){
- scanf("%d%d%d",&n,&m,&r);
- for(int i=;i<=n;i++)
- scanf("%lld",&v[i]),head[i]=-;
- for(int i=;i<n;i++){
- int u,v;
- scanf("%d%d",&u,&v);
- add(u,v); add(v,u);
- }
- dfs(r,-);
- for(int i=;i<=n;i++)
- update(in[i],v[i]);
- while(m--){
- int op,x,y;
- scanf("%d",&op);
- if(op==){
- scanf("%d%d",&x,&y);
- update(in[x],y);
- }
- else{
- scanf("%d",&x);
- printf("%lld\n",ask(out[x])-ask(in[x]-));
- }
- }
- return ;
- }
Loj 145 DFS序+树状数组区间更新区间查找
题目链接:https://loj.ac/problem/145
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- #define lson l,mid,rt<<1
- #define rson mid+1,r,rt<<1|1
- typedef long long ll;
- const ll maxn=1e6+;
- int n,q,m,r,tot,cnt;
- ll v[maxn],in[maxn],out[maxn],head[maxn],x,num[maxn],sum1[maxn],sum2[maxn];
- struct node{
- int to,next;
- }edge[*maxn];
- void add(int u,int v){
- edge[tot].to=v;
- edge[tot].next=head[u];
- head[u]=tot++;
- }
- void dfs(int pos,int fa){
- num[++cnt]=pos;
- in[pos]=cnt;
- for(int i=head[pos];i!=-;i=edge[i].next){
- int v=edge[i].to;
- if(v!=fa) dfs(v,pos);
- }
- out[pos]=cnt;
- }
- int lowbit(int x){return x&(-x);}
- void update(int x,ll y){
- for(int i=x;i<=n;i+=lowbit(i)){
- sum1[i]+=y;
- sum2[i]+=(x-)*y;
- }
- }
- ll ask(int x){
- ll res=;
- for(int i=x;i;i-=lowbit(i)){
- res+=x*sum1[i]-sum2[i];
- }
- return res;
- }
- int main(){
- scanf("%d%d%d",&n,&m,&r);
- for(int i=;i<=n;i++)
- scanf("%lld",&v[i]),head[i]=-;
- for(int i=;i<n;i++){
- int u,v;
- scanf("%d%d",&u,&v);
- add(u,v); add(v,u);
- }
- dfs(r,-);
- for(int i=;i<=n;i++)
- update(in[i],v[i]-v[num[in[i]-]]);
- while(m--){
- int op,x,y;
- scanf("%d",&op);
- if(op==){
- scanf("%d%d",&x,&y);
- update(in[x],y); update(out[x]+,-y);
- }
- else{
- scanf("%d",&x);
- printf("%lld\n",ask(out[x])-ask(in[x]-));
- }
- }
- return ;
- }
Libre OJ 144、145 (DFS序)的更多相关文章
- Comet OJ - Contest #11 D isaster 重构树+倍增+dfs序+线段树
发现对于任意一条边,起决定性作用的是节点编号更大的点. 于是,对于每一条边,按照节点编号较大值作为边权,按照最小生成树的方式插入即可. 最后用线段树维护 dfs 序做一个区间查询即可. Code: # ...
- BZOJ_4034 [HAOI2015]树上操作 【树链剖分dfs序+线段树】
一 题目 [HAOI2015]树上操作 二 分析 树链剖分的题,这里主要用到了$dfs$序,这题比较简单的就是不用求$lca$. 1.和树链剖分一样,先用邻接链表建双向图. 2.跑两遍$dfs$,其实 ...
- DFS序和7种模型
DFS序就是将树的节点按照先根的顺序遍历得到的节点顺序 性质:一个子树全在一个连续的区间内,可以与线段树和树状数组搭配使用 很好写,只需在dfs中加几行代码即可. 代码: void dfs(ll u, ...
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
随机推荐
- 通过修改Tomcat配置,解决乱码问题
贴图,问题如下: tomcat使用的默认编码方式是iso8859-1 修改tomcat下的conf/server.xml文件 找到如下代码: <Connector port="8 ...
- babel (三) babel polly-fill
Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate ...
- Thread类相关方法
线程对象 每一个线程都是和类Thread的实例相关联的.在Java中,有两种基本的使用Thread对象的方式,可用来创建并发性程序. 1.在应用程序需要发起异步任务的时候,只要生成一个Thread对 ...
- [转帖]Office全版本零售版转换VOL
Office全版本零售版转换VOL https://blog.51cto.com/10981246/2062137 转成bat 执行 改天试试 @ECHO OFF&PUSHD %~DP0 ...
- Linux基础学习(14)--日志管理
第十四章——日志管理 一.日志管理简介 1.日志服务: 2.常见日志的作用: 二. rsyslogd日志服务 1.日志文件格式: 2./etc/rsyslog.conf配置文件: 三.日志轮替 1.日 ...
- linux audit审计(8)--开启audit对系统性能的影响
我们使用测试性能的工具,unixbench,它有一下几项测试项目: Execl Throughput 每秒钟执行 execl 系统调用的次数 Pipe Throughput 一秒钟内一个进程向一个管道 ...
- WPF Image控件的绑定
在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对路径 ...
- 集合之ArrayList(含JDK1.8源码分析)
一.ArrayList的数据结构 ArrayList底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据.我们对ArrayList类的实例的所有的操作(增删改查等),其底层都 ...
- thymeleaf 简易使用范例
thymeleaf 范例: <!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/19 ...
- JQuery operate xml
msg is <?xml ?> <Parameters> <WorkflowName>...</WorkflowName> </Parameter ...