zoukankan      html  css  js  c++  java
  • 第五章总结

    二叉树

             定义很重要,没错,我就默一遍吧。(最简单的不写)

                  结点的度:结点拥有的子树个数(分支数);

        祖先:根到该结点所经分支上的所有的结点;

        树的度:树内结点度的最大值;

        树的高度(深度):树的最大层次;

      然后是二叉树的性质,也很重要我也来一遍吧。

     

     

     

     证明错了请指正!!!

      学习笔记

    树的dfs序(先序)

    题目:https://cn.vjudge.net/contest/283912#problem/J

      意思是给你一些属从关系,a  b ,代表b 是a 的上属,你可以给一个人分配任务,他和他所有下属都要做那个任务,然后可以查询一个人现在在做什么任务,无分配就输出-1;

      这题很容易想到并查集,但还可以用线段树做,通过懒惰标记来pushdowm任务,精髓是对每一个结点的子树dfs序编号,就把子树变成线性结构的一个区间了,从而可以很容易的通过递归更改任务。

      代码:

      1 #include<iostream>
      2 #include<vector>
      3 #include<cstring>
      4 #include<stdio.h>
      5 using namespace std;
      6 #define pb push_back
      7 const int N = 50005;//员工最多有那么多个
      8 
      9 vector <int> ve[N];//就建立那么多的树,ve[他]表示他为经理的一颗树
     10 bool vis[N];//用于标记数组
     11 int index;//时间戳中间变量
     12 int sta[N],en[N];//结点dfs序的开始与结束
     13 
     14 typedef struct Node{
     15     int task,lazy;
     16 }Node;
     17 Node tree[N << 2];
     18 void dfs(int k)
     19 {
     20     sta[k]=++index;
     21     int len=ve[k].size();
     22     for(int i=0;i<len;i++)
     23         dfs(ve[k][i]);
     24     en[k]=index;
     25 }
     26 
     27 void pushdown(int root)
     28 {
     29     if(tree[root].lazy )//有懒惰标记
     30     {
     31         tree[root * 2 + 1].lazy =tree[root * 2 + 2].lazy =tree[root].lazy ;//将现在结点的懒惰标记下传
     32         tree[root * 2 + 1].task =tree[root * 2 + 2].task =tree[root].task ;//下属的任务和经理相同
     33         tree[root].lazy =0;//经理的懒标记清空
     34     }
     35 }
     36 
     37 int query(int root,int l,int r,int index)//根,左,右,index是x号员工开始的时间戳
     38 {
     39     if( l==r && l==index )
     40         return tree[root].task ;
     41     pushdown(root);//对于每一次查询,更新root下面的懒标记和任务
     42     int mid=(l+r)/2;
     43     if(index<=mid)
     44     {//答案在左边
     45         return query(root*2+1,l,mid,index);
     46     }
     47     else//答案在右边
     48         return query(root*2+2,mid+1,r,index);//!!!!!!!!!!!!!!!!
     49 }
     50 
     51 void update(int root ,int l,int r,int pl,int pr,int task)//pl,pr是x号员工对应下属树的区间左和右,将他们全部更新为task
     52 {
     53     if( r<pl || pr<l)
     54         return;
     55     if(l >= pl && r <= pr )
     56     {
     57         tree[root].lazy =1;
     58         tree[root].task =task;
     59         return ;
     60     }
     61     pushdown(root);//对于没进入上面两个if,都要下传本次经理的懒标记和任务
     62     int mid=( l + r ) /2;
     63     if(pl<=mid){
     64         update(root *2+1,l,mid,pl,pr,task);
     65     }
     66     if(pr>mid)
     67     {
     68         update(root *2+2,mid+1,r,pl,pr,task);
     69     }
     70 }
     71 
     72 int main()
     73 {
     74     int cnt=0;//用于输出case的数字
     75     int t;
     76     scanf("%d",&t);
     77     while(t--)
     78     {
     79         int n;
     80         cnt++;
     81         scanf("%d",&n);
     82         for(int i=1;i<=n;i++)
     83             ve[i].clear();//先初始化全部经理树
     84         memset(vis,false,sizeof(vis));//初始化vis为负一
     85         for(int i=0;i<n-1;i++)
     86         {
     87             int u,v;
     88             cin>>u>>v;
     89             vis[u]=true;//记录的是u,下属!
     90             ve[v].pb(u);//把u放入名字为v的动态数组,表示u是v的下属
     91         }
     92         index=0;
     93 
     94         for(int i=1;i<=n;i++)
     95         {
     96             if(!vis[i]){
     97                 dfs(i);
     98                 break;
     99             }
    100         }
    101         for(int i=1;i<(N<<2);i++)
    102         {//初始化树的懒惰标记和任务
    103             tree[i].task =-1;//一开始没有任务,要输出-1
    104             tree[i].lazy =0;
    105         }
    106         printf("Case #%d:
    ",cnt);
    107 
    108         int M;
    109         cin>>M;
    110         while(M--)
    111         {
    112             char ch;
    113             cin>>ch;
    114             if(ch=='C'){//查询x号员工现在做的工作
    115                 int x;
    116                 cin>>x;
    117                 cout<<query(1,1,n,sta[x])<<endl;
    118             }
    119             else{
    120                 int x,y;
    121                 scanf("%d %d",&x,&y);
    122                 update(1,1,n,sta[x],en[x],y);//更新x的所有下属去做任务y
    123             }
    124         }
    125     }
    126     return 0;
    127 }

    目标:把主席树思想转化为代码,红黑树,字典树有时间搞搞。

         省赛前复习最小生成树,并查集,最短路径和深广搜。

        

  • 相关阅读:
    竞品选择的背后
    小程序UI
    效果CSS实现三角
    pmp心得
    [已读]响应式web设计实践
    [在读]HTML5程序设计(第二版)
    [已读]响应式web设计
    [已读]HTML5与CSS3权威指南第二版(下)
    [已读]编写可维护的javascript
    [未读]JavaScript高效图形编程
  • 原文地址:https://www.cnblogs.com/qq2210446939/p/10808818.html
Copyright © 2011-2022 走看看