hdu 3974 时间戳+线段树

 

每次染色子树,询问某个节点此时的颜色。

建树比较特殊,先dfs一遍用时间戳dfn给每个节点编号,

把该点的子树转化成它管辖的连续区间

照常染色即可

注意query的时候,问点q,传入参数应该是dfn(q),而非q。

--

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
using namespace std;
int cnt=0,Index=0,head[500000],fa[500000],dfn[500000],sta[500000],End[500000],lazy[500000],cover[500000];
struct lys{
    int to,from,next;
}edge[500000];
void add(int from,int to)
{
    cnt++;
    edge[cnt].next=head[from];
    edge[cnt].to=to;
    edge[cnt].from=from;
    head[from]=cnt;
}
void dfs(int u)
{  
    Index++;
    dfn[u]=Index;
    sta[u]=Index;
    for(int i=head[u];i;i=edge[i].next)
    {  
     if(!dfn[edge[i].to])     dfs(edge[i].to);
    }
    End[u]=Index;
}
//先检查时间戳
void pushdown(int rt)
{
    if(lazy[rt]==-1) return;
    lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
    lazy[rt]=-1;
}
void update(int rt,int l,int r,int ul,int ur,int k)
{   
    if((l>=ul)&&(r<=ur))
    {  
        lazy[rt]=k;
        return;
    }
    
    if(l>ur||r<ul) return;
    
    pushdown(rt);
    
    int mid=(l+r)>>1;
    
    if(ul<=mid) update(rt<<1,l,mid,ul,ur,k);
    if(ur>mid) update(rt<<1|1,mid+1,r,ul,ur,k);
}
int query(int rt,int l,int r,int q)
{
   //单点查询or lazytag    
   if(l==r)
   { 
         return lazy[rt];
   }
   
   pushdown(rt);
   
   int mid=(l+r)>>1;
   if(q<=mid)
   {
       return query(rt<<1,l,mid,q);
   }
   else return query(rt<<1|1,mid+1,r,q);
} 
int main( )
{
    
    //freopen("lys.in","r",stdin);
    /*
C 3 
T 2 1
C 3 
T 3 2 
C 3
T 4 100
T 5 10
C 3
C 4
C 2
T 2 50
C 3
    */
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {  memset(head,0,sizeof(head));
       memset(dfn,0,sizeof(dfn));
       memset(lazy,-1,sizeof(lazy));
       memset(cover,-1,sizeof(cover)); 
       memset(sta,0,sizeof(sta));
       memset(End,0,sizeof(End));
       Index=0;
       
       printf("Case #%d:\n",i);
        int n;cin>>n;
        
        for(int i=1;i<=n;i++) fa[i]=i;
        
        for(int j=1;j<=n-1;j++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
            fa[a]=b;
        }
    
        for(int i=1;i<=n;i++)
        {
            if(fa[i]==i) 
            {
                dfs(i);
                break;
            }
        }
        
        int m;
        cin>>m;
        for(int j=1;j<=m;j++)
        {   
            char type;
            int q,k;
            cin>>type;
            
            if(type=='C')
            {   scanf("%d",&q);
                printf("%d\n",query(1,1,n,dfn[q]));
            }
            else {
                scanf("%d%d",&q,&k);
                update(1,1,n,sta[q],End[q],k);
            }
        }
    }
}

 

posted @ 2021-10-30 09:35  liyishui  阅读(41)  评论(0编辑  收藏  举报