HDU-3974 DFS序+线段树

来源:互联网 发布:联通e是什么网络 编辑:程序博客网 时间:2024/06/06 14:05

题意:
一个公司里面每个员工都有一个上司,除了一个人没有上司(即老总也就相当于员工),一旦给某个员工分配任务后,这个员工以及其所有下属都在做该任务。 
    有两个操作,
    T:分配给员工任务
    C:查询该员工正在执行的任。 
题解:看着蛋疼,但是你想成一棵树就可以用DFS序列+线段树来解决问题了,这道题也让我知道我之前的区间判断的写法很不安全,之后将逐渐改成更为正确安全的写法。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define lson root<<1,l,mid#define rson root<<1|1,mid+1,rconst int MAXN=50000+7;bool mark[MAXN];struct Edge{    int to,next;}edge[MAXN];int head[MAXN],tot;int cnt;int in[MAXN],out[MAXN];struct node{    int l,r;    int lazy,val;}t[MAXN<<2];void init(){    cnt=0;    tot=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v){    edge[tot].to=v;    edge[tot].next=head[u];    head[u]=tot++;} void dfs(int u){    in[u]=++cnt;    for(int i=head[u];i!=-1;i=edge[i].next)    {        dfs(edge[i].to);    }    out[u]=cnt;}void build(int root,int l,int r){    t[root].l=l;    t[root].r=r;    t[root].lazy=0;    t[root].val=-1;    if(l==r) return ;    int mid=(l+r)/2;    build(lson);    build(rson);}void pushdown(int root){    if(t[root].lazy)    {        t[root<<1].lazy=t[root].lazy;        t[root<<1|1].lazy=t[root].lazy;        t[root<<1].val=t[root].lazy;        t[root<<1|1].val=t[root].lazy;        t[root].lazy=0;    }}void update(int root,int L,int R,int v){//  printf("L=%d  R=%d  t[root].l=%d  t[root].r=%d\n",L,R,t[root].l,t[root].r);    if(t[root].l==L&&t[root].r==R)    {        t[root].val=v;        t[root].lazy=v;        return ;    }    pushdown(root);    int mid=(t[root].l+t[root].r)/2;//  下面这段WA了,而之前用这种写法不会错,说明这种写法肯定有漏洞,不应该这样写, //  if(L<=mid)//  update(root<<1,L,mid,v);//  if(R>mid)//  update(root<<1|1,mid+1,R,v);    //下面这种写法最安全     if(R <= mid) update(root<<1,L,R,v);    else if(L > mid)update((root<<1)|1,L,R,v);    else    {        update(root<<1,L,mid,v);        update((root<<1)|1,mid+1,R,v);    }}int query(int root,int x){    if(t[root].l==x&&t[root].r==x)    return t[root].val;    pushdown(root);    int mid=(t[root].l+t[root].r)/2;    if(x<=mid)    query(root<<1,x);    else    query(root<<1|1,x); }int main(){    int T,n,m,i,k=1;    scanf("%d",&T);    while(T--)    {        memset(mark,false,sizeof(mark));        scanf("%d",&n);        int u,v;        init();        for(i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            mark[u]=true;            addedge(v,u);        }        for(i=1;i<=n;i++)        if(!mark[i])        dfs(i);        build(1,1,n);        scanf("%d",&m);        printf("Case #%d:\n",k++);//      for(i=1;i<=n;i++)//      printf("in[%d]=%d  out[%d]=%d\n",i,in[i],i,out[i]);        while(m--)        {            char s[2];            int x,y;            scanf("%s",&s);            if(s[0]=='C')            {                scanf("%d",&x);                printf("%d\n",query(1,in[x]));                          }            if(s[0]=='T')            {                scanf("%d%d",&x,&y);                update(1,in[x],out[x],y);            }        }    }} 
原创粉丝点击