zoukankan      html  css  js  c++  java
  • kb-07线段树--10--dfs序建树

      1 /*
      2    hdu3974
      3    dfs序建树,然后区间修改查询;
      4  */
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #define MAX_N 50005
     10 using namespace std;
     11 
     12 int N,M;
     13 struct Node
     14 {
     15     int to,next;
     16 }edge[MAX_N];
     17 struct TREE
     18 {//val记录的是区间;
     19     int l,r,val,lazy;
     20 }tr[MAX_N*4];
     21 int head[MAX_N],cnt,tot;
     22 int Start[MAX_N],End[MAX_N];
     23 
     24 void Addedge(int u,int v)//链式前向星存图;
     25 {
     26     //tot是边的编号;
     27     edge[tot].to=u;//以v为起点的边;终点是u;
     28     edge[tot].next=head[v];//这条边的下一条边是几号边,依然是v为起点的边;
     29     head[v]=tot++;//更新v为起点的边的入口;
     30 }
     31 void dfs(int x)
     32 {
     33     cnt++;//初始为0;这里是1了,从1开始编号;
     34     Start[x]=cnt;//起点是x的编号
     35     for(int i=head[x];i!=-1;i=edge[i].next)//遍历以v为起点的边;
     36     {
     37         dfs(edge[i].to);
     38     }
     39     End[x]=cnt;//遍历完子树后可以得到这个树根的编号范围就是star&end;
     40     //dfs先根遍历,把x为根的子树的所有的节点编号在一段区间内,连续编号,并且记录该区间的编号起始和结束,当线段树修改值的时候就直接修改该区间;
     41 }
     42 void build(int rt,int l,int r)
     43 {
     44     tr[rt].l=l;
     45     tr[rt].r=r;
     46     tr[rt].val=-1;
     47     tr[rt].lazy=0;
     48     if(l==r)
     49         return;
     50     int mid=(l+r)/2;
     51     build(rt<<1,l,mid);
     52     build(rt<<1|1,mid+1,r);
     53 }
     54 void Pushdown(int rt)
     55 {
     56     int ls=rt<<1,rs=rt<<1|1;
     57     if(tr[rt].lazy)
     58     {
     59         tr[rs].val=tr[ls].val=tr[rt].val;
     60         tr[rs].lazy=tr[ls].lazy=1;
     61         tr[rt].lazy=0;
     62     }
     63 }
     64 void Update(int rt,int l,int r,int x)
     65 {
     66     if(tr[rt].l==l&&tr[rt].r==r)
     67     {
     68         tr[rt].val=x;
     69         tr[rt].lazy=1;
     70         return ;
     71     }
     72     Pushdown(rt);
     73     int ls=rt<<1,rs=rt<<1|1;
     74     if(l<=tr[ls].r)
     75     {
     76         if(r<=tr[ls].r)
     77             Update(ls,l,r,x);
     78         else
     79             Update(ls,l,tr[ls].r,x);
     80     }
     81     if(r>=tr[rs].l)
     82     {
     83         if(l>=tr[rs].l)
     84             Update(rs,l,r,x);
     85         else
     86             Update(rs,tr[rs].l,r,x);
     87     }
     88 }
     89 int Query(int rt,int a)
     90 {
     91     if(tr[rt].l==a&&tr[rt].r==a)
     92     {
     93         return tr[rt].val;
     94     }
     95     Pushdown(rt);
     96     int mid=(tr[rt].l+tr[rt].r)/2;
     97     if(a<=mid)
     98         return Query(rt<<1,a);
     99     else
    100         return Query(rt<<1|1,a);
    101 }
    102 int main()
    103 {
    104     int T,k=1;
    105     cin>>T;
    106     while(T--)
    107     {
    108         printf("Case #%d:
    ",k++);
    109         cnt=0;
    110         tot=0;
    111         memset(edge,0,sizeof(edge));
    112         memset(head,-1,sizeof(head));
    113         memset(Start,-1,sizeof(Start));
    114         memset(End,-1,sizeof(End));
    115         bool used[MAX_N];
    116         memset(used,false,sizeof(used));
    117         cin>>N;
    118         for(int i=0;i<N-1;i++)
    119         {
    120             int u,v;
    121             cin>>u>>v;//v是u的上级;
    122             used[u]=true ;//表示u是有上级的,也就是有入度的;
    123             Addedge(u,v);
    124         }
    125         for(int i=1;i<=N;i++)
    126         {
    127             if(!used[i])//找到入度为0的点,就是整个树的入口;
    128             {
    129                 dfs(i);
    130                 break;
    131             }
    132         }
    133         build(1,1,N);
    134         cin>>M;
    135         for(int i=0;i<M;i++)
    136         {
    137             char a[10];
    138             scanf("%s",a);
    139             if(a[0]=='C')
    140             {
    141                 int x;
    142                 cin>>x;
    143                 int ans=Query(1,Start[x]);//该点的编号就是起点的编号;
    144                 cout<<ans<<endl;
    145             }
    146             else
    147             {
    148                 int a,b;
    149                 cin>>a>>b;
    150                 Update(1,Start[a],End[a],b);
    151             }
    152         }
    153 
    154     }
    155     return 0;
    156 }
  • 相关阅读:
    实现只有0,1,2三种元素的乱序数组的排序
    请说明Request和Session的生命周期
    使用Enumeration和Iterator遍历集合类
    hive中分组取前N个值的实现
    世界知名网站的技术实现(转)
    蚂蚁变大象:浅谈常规网站是如何从小变大的(转)
    Hadoop管理员的十个最佳实践(转)
    internet笔记
    Instagram 架构分析笔记(转)
    Apache Pig入门 –介绍/基本架构/与Hive对比(转)
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4542975.html
Copyright © 2011-2022 走看看