J - Assign the task

J - Assign the task

HDU - 3974

思路:一眼秒思路<(* ̄▽ ̄*)/

dfs序+线段树。

通过dfs序把树上问题转化成线段上的问题。然后用线段树解决。

错因:都是些zz的错误就不说了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50010
using namespace std;
int t,n,m;
int sz,tot,sum,root;
int to[MAXN*2],net[MAXN*2],head[MAXN];
int dad[MAXN],idl[MAXN],idr[MAXN],edge[MAXN];
struct nond{
    int l,r,flag;
}tree[MAXN*4];
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
}
void build(int now,int l,int r){
    tree[now].l=l;tree[now].r=r;
    tree[now].flag=-1;
    if(tree[now].l==tree[now].r)    return ;
    int mid=(tree[now].l+tree[now].r)/2;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
}
void down(int now){
    tree[now*2].flag=tree[now*2+1].flag=tree[now].flag;
    tree[now].flag=-1;
    return ;
}
void change(int now,int l,int r,int pos){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].flag=pos;
        return ;
    }
    if(tree[now].flag!=-1)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    change(now*2,l,r,pos);
    else if(l>mid)    change(now*2+1,l,r,pos);
    else { change(now*2,l,mid,pos);change(now*2+1,mid+1,r,pos); }
}
int query(int now,int x){
    if(tree[now].l==tree[now].r)
        return tree[now].flag;
    if(tree[now].flag!=-1)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(x<=mid)    return query(now*2,x);
    else return query(now*2+1,x);
}
void dfs(int now){
    idl[now]=++sz;
    for(int i=head[now];i;i=net[i])
        if(dad[now]!=to[i]){
            dad[to[i]]=now;
            dfs(to[i]);
        }
    idr[now]=++sz;
}
int main(){
    scanf("%d",&t);
    while(t--){
        sum++;printf("Case #%d:\n",sum);
        scanf("%d",&n);tot=0;
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(v,u);edge[u]++;
        }
        for(int i=1;i<=n;i++)
            if(edge[i]==0){ root=i;break; }
        dfs(root);build(1,1,sz);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            char c;int x,y;
            scanf("\n%c%d",&c,&x);
            if(c==‘T‘){
                scanf("%d",&y);
                change(1,idl[x],idr[x],y);
            }
            else    printf("%d\n",query(1,idl[x]));
        }
        root=0;sz=0;
        memset(to,0,sizeof(to));
        memset(idl,0,sizeof(idl));
        memset(idr,0,sizeof(idr));
        memset(net,0,sizeof(net));
        memset(dad,0,sizeof(dad));
        memset(edge,0,sizeof(head));
        memset(head,0,sizeof(head));
    }
}
/*
1
5
4 3
3 2
1 3
5 2
5
C 3
T 2 1
 C 3
T 3 2
C 3
*/

原文地址:https://www.cnblogs.com/cangT-Tlan/p/8470236.html

时间: 2024-11-07 13:54:31

J - Assign the task的相关文章

J - Assign the task - hdu 3974(多操作混合区间更新)线段树

题意:有四种操作 1,  区间 [l, r] 的值都加上 C 2,  区间 [l, r] 的值都乘上 C 3,  区间 [l, r] 的值都变为C 4,  求区间 [l, r]所有数的p次方的和 分析:是比较麻烦的区间操作,设计四种操作,更新的时候无法更新到底部,不过仔细思考可以想到这都是对区间进行的操作,所以会造成一部分的区间值相等,所以只需要更新到相等区间部分就行了,而且注意有第三种操作的时候,第二和第一种操作可以去掉,操作的优先性是3>2>1,. WA了一次,因为操作三进行的的时候没有把

J - Assign the task HDU - 3974 (线段树 + dfs序)

题意:给一颗树,两种操作,查询 i 结点的颜色,和将i结点和它的子树都染成另一种颜色 题解:dfs序构建线段树,对于x和其子树染色就是 l[x] 和 r[x]; dfs序线段树板子 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue>

HDU 3974 Assign the task 并查集/图论/线段树

Assign the task Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3974 Description There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the l

HDU 3974 Assign the task(树 并查集)

题意  公司中有n个员工  除了boss  每个员工都有自己的上司  自己下属的下属也是自己的下属  当给一个员工分配任务时  这个员工会把任务也分配到自己的所有下属   每个员工都只做最后一个被分配的任务  对于每个C x  输出员工x正在做的任务  没有就输出-1 把员工的关系数建成类似并查集的结构  把每个直接分配任务的员工的任务和任务分配时间保存起来  查询时只要找这个员工所有父节点中最晚分配的任务 #include <bits/stdc++.h> using namespace st

线段树+dfs序(Apple Tree )(Assign the task )

线段树+dfs序 给定一棵n个节点的树,m次查询,每次查询需要求出某个节点深度为h的所有子节点. 作为预处理,首先将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致. 然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]. 最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出

HDU 3974 Assign the task(并查集)

Problem Description There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss of someone,that person is your subordinate, an

HDU 3974 Assign the task(线段树)

描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss of someone,that person is your subordinate, and all his subordin

HDU 3947 Assign the task

http://acm.hdu.edu.cn/showproblem.php?pid=3974 Problem Description There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss

HDU 3974 Assign the task 简单搜索

根据Rex 的思路才知道可以这么写. 题目意思还是很好理解的,就是找到当前雇员最近的任务. 做法是,可以开辟一个 tim 变量,每次有雇员得到昕任务时候 ++tim 然后取寻找最近的任务的时候写一个搜索就可以 核心代码: while(num != -1){ num = a[num].leader; if(ttime < a[num].time){ ans = a[num].work; ttime = a[num].time; } } Source code: //#pragma comment(