zoukankan      html  css  js  c++  java
  • HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)

    题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树)。当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工作),题目会询问你其中某个人正在做的工作。

    解题思路:其实从“一个人分配他的下属做一样的工作”这里就可以看出来了,这相当于让一块区间的人都做一样的事,就是线段树区间染色问题。但不能使用线段树,要先将多叉树铺展开,将节点映射到线段上。把每个人的管理区段找出来(把属于同一个人管的放一起,上司放在前面),这样对某个员工更新也就是对他和他下属的更新。具体实现就是先将多叉树保存下来,用dfs遍历多叉树给每个人打上时间戳,分配序号就行了。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<vector>
      4 #define LC(a) ((a<<1))
      5 #define RC(a) ((a<<1)+1)
      6 #define MID(a,b) ((a+b)>>1)
      7 using namespace std;
      8 const int N=5e4+5;
      9 typedef long long ll;
     10 
     11 vector<ll>v[N];
     12 ll Start[N],End[N];//每个员工所有下属的开始和结束节点,包含本身
     13 ll ans,cnt;//cnt用于记录节点的编号
     14 bool used[N];
     15 
     16 void dfs(ll rt){
     17     Start[rt]=++cnt;
     18     for(int i=0;i<v[rt].size();i++){
     19         dfs(v[rt][i]);
     20     }
     21     End[rt]=cnt;
     22 }
     23 
     24 struct node{
     25     ll l,r;
     26     ll task;//task=-2表示下属工作不同 
     27 }tree[N*4];
     28 
     29 void pushup(ll p){
     30     tree[p].task=(tree[LC(p)].task==tree[RC(p)].task?tree[LC(p)].task:-2);
     31 }
     32 
     33 void pushdown(ll p){
     34     tree[LC(p)].task=tree[RC(p)].task=tree[p].task;
     35 }
     36 
     37 void build(ll p,ll l,ll r){
     38     tree[p].l=l;
     39     tree[p].r=r;
     40     tree[p].task=-1;
     41     if(l==r){
     42         return;
     43     }
     44     build(LC(p),l,MID(l,r));
     45     build(RC(p),MID(l,r)+1,r);
     46 }
     47 
     48 void update(ll p,ll l,ll r,ll task){
     49     if(r<tree[p].l||l>tree[p].r)
     50         return;
     51     if(l<=tree[p].l&&r>=tree[p].r){
     52         tree[p].task=task;
     53         return;
     54     }
     55     if(tree[p].task!=-2)
     56         pushdown(p);
     57     update(LC(p),l,r,task);
     58     update(RC(p),l,r,task);
     59     pushup(p);
     60 }
     61 
     62 void query(ll p,ll t){
     63     if(tree[p].task!=-2){
     64         ans=tree[p].task;
     65         return;
     66     }
     67     ll mid=MID(tree[p].l,tree[p].r);
     68     if(t<=mid)
     69         query(LC(p),t);
     70     else
     71         query(RC(p),t);
     72 }
     73 
     74 int main(){
     75     ios::sync_with_stdio(false);
     76     ll t;
     77     ll cas=0;
     78     cin>>t;
     79     while(t--){
     80         cas++;
     81         //初始化 
     82         cnt=0; 
     83         memset(used,false,sizeof(used));
     84         for(int i=1;i<=N;i++){
     85             v[i].clear();
     86         }
     87         
     88         ll n;
     89         cin>>n;
     90         for(int i=1;i<=n-1;i++){
     91             ll    rt,chd;
     92             cin>>chd>>rt;
     93             used[chd]=true;
     94             v[rt].push_back(chd);
     95         }
     96         //将多叉树转化为线段 
     97         for(int i=1;i<=n;i++){
     98             //找到根结点 
     99             if(!used[i]){
    100                 dfs(i);
    101                 break;
    102             }
    103         }
    104         //建树 
    105         build(1,1,n); 
    106         ll m;
    107         cout<<"Case #"<<cas<<":"<<endl;
    108         cin>>m;    
    109         for(int i=1;i<=m;i++){
    110             char op;
    111             cin>>op;
    112             if(op=='C'){
    113                 ll x,t;
    114                 cin>>x;
    115                 t=Start[x];
    116                 query(1,t);
    117                 cout<<ans<<endl;
    118             }
    119             else{
    120                 ll x,l,r,task;
    121                 cin>>x>>task;
    122                 l=Start[x];
    123                 r=End[x];
    124                 update(1,l,r,task);
    125             }
    126         }            
    127     }
    128 }
  • 相关阅读:
    第72届奥斯卡最佳动画奖《老人与海》
    关不掉的手机应用程序
    李嘉诚:知识并不一定使你的财富增加
    Linux之父Linus Torvalds谈软件开发管理经验
    Google 正式发布Dart编程语言
    代码本身其实并不重要,重要的是用户
    22个基于HTML5开发的网站
    看看耶鲁大学心态 ,送给正在奋斗的人 !
    用 git 维护 vim 代码
    谈程序语言的设计及程序员心态
  • 原文地址:https://www.cnblogs.com/fu3638/p/7148304.html
Copyright © 2011-2022 走看看