1.cpu 

前言

  • 树链剖分是什么?

style=”font-size: 14pt;”>树链剖分,说白了就是相同种被你代码不得不强行扩充1k底数据结构-dms

  个人知道:+1:joy:

  • 发出什么用?

表达出题人万分毒瘤

足十分友(bao)好(li)的解决部分树上问题:grimacing:

(友情提示:学树链剖分在此以前请先精晓线段树)

#lscpu命令,查看的是cpu的总括新闻.(部分老本子不协理)

主旨思想

树链剖分的研究比较神奇

她的思是:拿同株树拆成多少单不交的链子,**然后用有数据结构去维护那些链**

 

这问题来了

  •  如何将培育拆成链?

先是肯定有定义

重儿子:该节点的子树中,节点个数最多之子树的绝望节点(也不怕是暨欠节点相连的点),即为该节点的重儿子

重边:连接该节点和它的重外儿子的界限

重链:由同样密密麻麻重边相连得到的链

轻链:由同名目繁多非重边相连拿到的链

这样即使容易得到拆树的法门

对每一个节点,找来她的重外儿子,那么就棵树就自可是然的受拆成了多重链与成千上万轻链

  •  怎么样对这么些链进行尊敬?

首先,要对那多少个链举办珍爱,就要管每个链上的节点都是连的,

故而大家需要针对整棵树举办又编号,然后用dfs序的合计,用线段树要树状数组等展开维护(具体用什么用看题目要求,因为线段树的效果比树状数组强大,所以当此地自己就是不提供树状数组的写法了)

 注目的在于拓展双重编号的时候先访问重链

那般可保重链内的节点编号连续

 

点说的万分肤浅了,结合一布置图来精通一下

对此同样蔸最主题的培训

图片 1

 

为他记重男,

 图片 2褐色为主儿子,褐色为重边

下一场针对树举行更编号

图片 3绿色表示的凡拖欠节点重新编号后底序号

不难看出重链内之节点编号是接二连三的

 

 

下一场就可以线段树上干工作呀

比如啊区间加区间求和什么的

此外有一个性能:因为$i$为彻底之子树的树在线段树上的号码也$[i,i+子树节点数-1]$

 

连通下去做并例题,加深一下对代码的明亮

 

 

代码

题材链接

树链剖分的裸题

首先来平等垛定义

 

int deep[MAXN];//节点的深度 
int fa[MAXN];//节点的父亲 
int son[MAXN];//节点的重儿子 
int tot[MAXN];//节点子树的大小 

 

Disk /dev/sda: 64.4 GB, 64424509440 bytes
255 heads, 63 sectors/track, 7832 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000859f

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              64        7833    62401536   8e  Linux LVM

Disk /dev/mapper/vg_qdy-lv_root: 53.7 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

第一步

随我们地点说之,大家先是要针对整棵树dfs一全,找有每个节点的重外甥

附带处理暴发每个节点的纵深,以及她们的姑丈节点

int dfs1(int now,int f,int dep)
{
    deep[now]=dep;
    fa[now]=f;
    tot[now]=1;
    int maxson=-1;
    for(int i=head[now];i!=-1;i=edge[i].nxt)
    {
        if(edge[i].v==f) continue;
        tot[now]+=dfs1(edge[i].v,now,dep+1);
        if(tot[edge[i].v]>maxson) maxson=tot[edge[i].v],son[now]=edge[i].v;
    }
    return tot[now];
}

 

 

第二步

然后我们要针对整棵树举办再编号

自拿同开头的每个节点的权值存在了$b$数组内

void dfs2(int now,int topf)
{
    idx[now]=++cnt;
    a[cnt]=b[now];
    top[now]=topf;
    if(!son[now]) return ;
    dfs2(son[now],topf);
    for(int i=head[now];i!=-1;i=edge[i].nxt)
        if(!idx[edge[i].v])
            dfs2(edge[i].v,edge[i].v);
}

$idx$表示又编号后该节点的号是小

此外,这里引入了一个$top$数组,

$top[i]$表示$i$号节点所在重链的头节点(最顶上的节点)

至于这数组有吗用,前边再说

 

 

第三步

咱需要基于重新编完号的造,把及时株树之高达每个点映射到线树上,

struct Tree
{
    int l,r,w,siz,f;
}T[MAXN];

void Build(int k,int ll,int rr)
{
    T[k].l=ll;T[k].r=rr;T[k].siz=rr-ll+1;
    if(ll==rr)
    {
        T[k].w=a[ll];
        return ;
    }
    int mid=(ll+rr)>>1;
    Build(ls,ll,mid);
    Build(rs,mid+1,rr);
    update(k);
}

此外线段树的基本操作,

这边就非详细表达了

直白放代码

void update(int k)//更新
{
    T[k].w=(T[ls].w+T[rs].w+MOD)%MOD;
}

void IntervalAdd(int k,int ll,int rr,int val)//区间加
{
    if(ll<=T[k].l&&T[k].r<=rr)
    {
        T[k].w+=T[k].siz*val;
        T[k].f+=val;
        return ;
    }
    pushdown(k);
    int mid=(T[k].l+T[k].r)>>1;
    if(ll<=mid)    IntervalAdd(ls,ll,rr,val);
    if(rr>mid)    IntervalAdd(rs,ll,rr,val);
    update(k);
}

int IntervalSum(int k,int ll,int rr)//区间求和
{
    int ans=0;
    if(ll<=T[k].l&&T[k].r<=rr)
        return T[k].w;
    pushdown(k);
    int mid=(T[k].l+T[k].r)>>1;
    if(ll<=mid) ans=(ans+IntervalSum(ls,ll,rr))%MOD;
    if(rr>mid)  ans=(ans+IntervalSum(rs,ll,rr))%MOD;
    return ans;
}

void pushdown(int k)//下传标记
{
    if(!T[k].f) return ;
    T[ls].w=(T[ls].w+T[ls].siz*T[k].f)%MOD;
    T[rs].w=(T[rs].w+T[rs].siz*T[k].f)%MOD;
    T[ls].f=(T[ls].f+T[k].f)%MOD;
    T[rs].f=(T[rs].f+T[k].f)%MOD;
    T[k].f=0;
}

 

使用#cat  /proc/cpuinfo ,可以解每个cpu信息,如每个CPU的型号,主频等。

第四步

我们考虑怎么样落实对树上的操作

树链剖分的思是:对此个别单不在同等重链内之节点,让她们绵绵地跳,使得他们处于相同重链上

那怎么样”跳”呢?

尚记我们当亚差$dfs$中著录之$top$数组么?

发出一个明了的结论:$x$到$top[x]$中之节点在线段树上是接二连三的,

结合$deep$数组

倘多只节点也$x$,$y$

咱每一回给$deep[top[x]]$与$deep[top[y]]$中生之(在脚的)往上跳(有点类似于树上倍增)

于x节点直接跨越到$top[x]$,然后在线段树上更新

最后两单节点肯定是处在同一漫长重链的,前面我们干过重链上的节点都是连续的,直接当线段树上举行相同浅查询就好

void TreeSum(int x,int y)//x与y路径上的和
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        ans=(ans+IntervalSum(1,idx[ top[x] ],idx[x]))%MOD;
        x=fa[ top[x] ];
    }
    if(deep[x]>deep[y]) swap(x,y);
    ans=(ans+IntervalSum(1,idx[x],idx[y]))%MOD;
    printf("%d\n",ans);
}

void TreeAdd(int x,int y,int val)//对于x,y路径上的点加val的权值
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        IntervalAdd(1,idx[ top[x] ],idx[x],val);
        x=fa[ top[x] ];
    }
    if(deep[x]>deep[y])    swap(x,y);
    IntervalAdd(1,idx[x],idx[y],val);
}

当树上查询的及时同样步可能略不着边际,我们结合一个事例来解一下

要点这张图,假而我们如果查询$3.6$这简单单节点的中的点权合,为了有利于清楚我们要每个点的点权都是$1$

图片 4

见惯不惊起通常

$top[3]=2,top[6]=1$

$deep[top[3]]=2,deep[top[6]]=1$

俺们会见给$3$向达跳,跳到$top[3]$的爸爸,也就是$1$号节点

图片 5

就是$1$号节点和$6$声泪俱下节点都当同样条还链内,所以一向指向线段树举办同样破查询即可


对子树的操作

本条就再也简便了

坐平蔸树之子树在线段树上是接二连三的

所以修改的上向来这样

IntervalAdd(1,idx[x],idx[x]+tot[x]-1,z%MOD);

 

2.内存

时光复杂度

(刚起忘记写了,这无异块是后来加及之)

#free -m #
查看内存使用量和互换区使用量   

性质1

如果边$\left(
u,v\right)$,为轻边,那么$Size\left( v\right) \leq Size\left(
u\right) /2$。

征:分明:joy:,否则该边会成为重边

  total       used       free     shared    buffers     cached
Mem:          3690        288       3401          0         15        119
-/+ buffers/cache:        153       3536
Swap:         3951          0       3951

性质2

作育被随意五只节点内的路线中好边的条数不会晤抢先$\log
_{2}n$,重路径的数目不会师跳$\log _{2}n$

证明:不会:stuck_out_tongue_winking_eye:

 

生了下边两修性质,我们就可以来分析时复杂度了

由还路径的数量的上界为$\log
_{2}n$,

丝段树被查询/修改的复杂度为$\log
_{2}n$

这就是说究竟的复杂度就是$\left( \log
_{2}n\right) ^{2}$

 # cat /proc/meminfo 

例题

#dmidecode -t memory 查看内存硬件消息

洛谷P3379 【模板】最近公共祖先(LCA)

树剖可以要LCA,没悟出吧

http://www.cnblogs.com/zwfymqz/p/8097366.html

 

洛谷P2590 [ZJOI2008]培训之总计

http://www.cnblogs.com/zwfymqz/p/7157156.html

当下卖代码是先前写的,可能较丑,下边两客是刚写的

grep MemTotal /proc/meminfo# 查看内存总量

洛谷P3178 [HAOI2015]树上操作

http://www.cnblogs.com/zwfymqz/p/8094286.html

grep MemFree /proc/meminfo # 查看空闲内存量

洛谷P3038 [USACO11DEC]牧草种植Grass Planting

有点意思

http://www.cnblogs.com/zwfymqz/p/8094429.html

lsmod # 列出加载的内核模块


3.磁盘

# lsblk 查看硬盘与分分而

图片 6图片 7

1 NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
2 sda                         8:0    0   60G  0 disk 
3 ├─sda1                      8:1    0  500M  0 part /boot
4 └─sda2                      8:2    0 59.5G  0 part 
5   ├─vg_qdy-lv_root (dm-0) 253:0    0   50G  0 lvm  /
6   ├─vg_qdy-lv_swap (dm-1) 253:1    0  3.9G  0 lvm  [SWAP]
7   └─vg_qdy-lv_home (dm-2) 253:2    0  5.7G  0 lvm  /home
8 sr0                        11:0    1 1024M  0 rom  

View Code

 

#df -h    # 查看各种分区使用状态

#du -sh # 查看指定目录的轻重

Filesystem                  Size  Used Avail Use% Mounted on
/dev/mapper/vg_qdy-lv_root   50G  3.7G   44G   8% /
tmpfs                       1.9G     0  1.9G   0% /dev/shm
/dev/sda1                   485M   39M  421M   9% /boot
/dev/mapper/vg_qdy-lv_home  5.6G  239M  5.1G   5% /home

#fdisk -l # 查看有分区详细新闻

Disk /dev/sda: 64.4 GB, 64424509440 bytes
255 heads, 63 sectors/track, 7832 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000859f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              64        7833    62401536   8e  Linux LVM
Disk /dev/mapper/vg_qdy-lv_root: 53.7 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
...... 下方省略!

 


4.网卡信息

# lspci | grep -i ‘eth’  查看网卡硬件音讯

# ifconfig -a
查看系统有网络接口

或 #ip link show 

# ethtool eth0 查看有网络接口的详细信息


5.主板所有硬件槽PCI信息。

#lspci

还详尽的lspci -v 或者 lspci -vv

#lscpi -t 设备树


6.查看bios 信息

# dmidecode -t bios


  1. 查阅系统运转时刻、用户数、负载

#uptime 

#cat /proc/loadavg # 查看系统负荷磁盘和分区

8. 查挂接的分区状态

#mount | column -t

  1. 翻看系统负载 磁盘和分区

# cat /proc/loadavg 

10.查看所有安装之软件包

 #rpm -qa

11. 翻有进程

# ps -ef 

12. 翻看有监听端口

#netstat -lntp 

13.查用户以及组音讯

#cut -d: -f1 /etc/passwd #
查看系统有着用户 cat /etc/passwd |more 呈现长系统用户并分页

#cut -d: -f1 /etc/group #
查看系统所有组   cat /etc/group|more 展现长系统所有组并分页

14任何不常用查看消息命令

swapon -s # 查看所有互换分区

iptables -L # 查看防火墙设置

hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备)

dmesg | grep IDE # 查看启动时IDE设备检测情况网络

crontab -l # 查看时用户的计划任务 服务

chkconfig –list # 列出富有系统服务#

chkconfig –list | grep on # 列出有启动之网服务 程序