• hdu3974 Assign the task线段树 dfs序


    题意:
    无序的给编号为1-n的员工安排上下级,
    操作一:给一个员工任务C,则该员工以及他的下级任务都更换为任务C
    操作二:询问一个员工,返回他的任务
     
    题解:
    给一个员工任务,则他所在组都要改变,联想到线段树的区间修改,但是这里是对一个人操作,不是区间操作,如果能把“点”操作变成“区间”操作责问题就转化为区间修改和单点查询问题了,这里用dfs序把原状态的点映射到一条线上去
     
    dfs序
    找到一个没有父亲的点
    按照下图求出他的l和r,每次进入的时候都加一,返回的时候不加
    编号     1 2 3 4 5
    左端点 4 1 3 5 2
    右端点 4 5 5 5 2
    即2号点他左端到1,右端到5
     
     

    单点查询:
    查询x,则可以理解为查询l[x]或r[x](下属和自己的工作一致)
    区间修改:
    比如上图改变2即改变1,5
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int N=1e5+90;
      4 const int inf=1e9+90;
      5 #define eps 1e-10
      6 #define forn(i,n) for(int i=0;i<n;i++)
      7 #define form(i,n) for(int i=1;i<=n;i++)
      8 typedef long long ll ;
      9 typedef unsigned long long ull ;
     10 #define ls l,mid,p<<1
     11 #define rs mid+1,r,p<<1|1
     12 int a[N];
     13 int n,m,root,rt;
     14 int to[N],ver[N],h[N],tot;
     15 char c[2];
     16 void add(int x,int y){
     17     to[++tot]=h[x];
     18     ver[tot]=y;
     19     h[x]=tot;
     20 }
     21 struct Node{
     22     int l,r;
     23     ll sum;
     24 }t[N<<2];
     25 int ml[N],mr[N];
     26 void dfs(int x){
     27     //进来的时候+1,
     28     ml[x]=++rt;
     29     for(int i=h[x];~i;i=to[i]){
     30         dfs(ver[i]);
     31     }
     32     mr[x]=rt;//返回的时候不需要+1
     33 }
     34 void pd(int p){
     35     if(t[p].sum!=-1){
     36         t[p<<1].sum=t[p<<1|1].sum=t[p].sum;
     37         t[p].sum=-1;
     38     }
     39 }
     40 void build(int l,int r,int p){
     41     if(l==r){
     42         t[p].l=t[p].r=l;
     43         t[p].sum=-1;
     44         return;
     45     }
     46     t[p]={l,r,-1};
     47     int mid=l+r>>1;
     48     build(l,mid,p<<1);
     49     build(mid+1,r,p<<1|1);
     50 }
     51 void modify(int l,int r,int c,int p){
     52     if(l<=t[p].l&&t[p].r<=r){
     53         t[p].sum=c;
     54         return;
     55     }
     56     pd(p);
     57     int mid=t[p].l+t[p].r>>1;
     58     if(l<=mid)modify(l,r,c,p<<1);
     59     if(r>mid)modify(l,r,c,p<<1|1);
     60 }
     61 int query(int x,int p){
     62     if(t[p].l==t[p].r)return t[p].sum;
     63     pd(p);
     64     int mid=t[p].l+t[p].r>>1;
     65     int ans=-1;
     66     if(x<=mid)ans=query(x,p<<1);
     67     else ans=query(x,p<<1|1);
     68     return ans;
     69 }
     70 int main(){
     71 //    freopen("in.txt","r",stdin);
     72 //    freopen("out.txt","w",stdout);
     73     int T,x,y;
     74     cin>>T;
     75     form(k,T){
     76         printf("Case #%d:
    ",k);
     77         scanf("%d",&n);
     78         memset(a,0,sizeof(a));
     79         memset(h,-1,sizeof(h));
     80         tot=0,rt=0;
     81         forn(i,n-1) {
     82             scanf("%d%d", &x, &y);
     83             add(y,x);
     84             a[x] = 1;
     85         }
     86         form(i,n){
     87             if(!a[i]){
     88                 root=i;
     89                 break;
     90             }
     91         }
     92         scanf("%d",&m);
     93         dfs(root);
     94         build(1,n,1);
     95         forn(i,m){
     96             scanf("%s",c);
     97             if(c[0]=='C'){
     98                 scanf("%d",&x);
     99                 printf("%d
    ",query(ml[x],1));
    100             }else{
    101                 scanf("%d%d",&x,&y);
    102                 modify(ml[x],mr[x],y,1);
    103             }
    104         }
    105     }
    106 }
  • 相关阅读:
    初识STM32标准库
    自己写库—构建库函数雏形
    使用寄存器点亮LED等
    新建工程---寄存器版
    什么是寄存器
    初识STM32
    ST-LINK驱动的安装
    MDK5使用技巧
    开发环境的搭建
    1行Python代码制作动态二维码
  • 原文地址:https://www.cnblogs.com/ilikeeatfish/p/13938779.html
Copyright © 2020-2023  润新知