Assign the task HDU

来源:互联网 发布:fannel扁平网络 编辑:程序博客网 时间:2024/05/21 21:37

题意:题意就是给你一颗树,然后如果你给一节点上赋值,那么他下面的所以子节点都会被赋上这个值,现在有两个操作:1 查询某个节点上的值,2.修改某个节点上的值 (注意他下面的值也会改变)

点击打开链接

思路:就是,我们在树上跑一边dfs然后给这颗树上的每个节点都重新编号,得到一个high数组和一个low数组,其实high数组表示的是区间左端点,low数组表示的区间右端点


之后就是对区间进行的操作了 ,然后查询就单点查询就好了 ,相通了还是挺简单的上代码:

#include <stdio.h>#include <string.h>#include <algorithm>#define lson l , m ,rt<<1#define rson m+1,r,rt<<1|1const int maxn =  50200;int sum[maxn<<2] , high[maxn] , low[maxn];  //high 管辖的头结点  low 尾节点int head[maxn] , cnt , vis[maxn],tot , p[maxn] , n ,lazy[maxn<<2];struct node{int to,next;}edg[maxn<<1];void add(int u ,int v){edg[cnt].to=v;edg[cnt].next = head[u];head[u] = cnt++;}void init(){memset(head,-1,sizeof(head));memset(lazy,0,sizeof(lazy));memset(sum,0,sizeof(sum));memset(high,0,sizeof(high));memset(low,0,sizeof(low));cnt = 0 ;tot = 0 ;for(int i = 1 ; i <= n ;i++){p[i] = i;}}int getf(int v){return p[v] = v ? p[v] : getf(v);}void dfs(int v){if(vis[v]) return ;high[v] = ++tot;for(int i = head[v] ; i!=-1 ; i = edg[i].next){int p = edg[i].to;dfs(p);}low[v] = tot;}void pushdown(int rt){if(lazy[rt] != 0 ){lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];sum[rt<<1] = lazy[rt];sum[rt<<1|1] = lazy[rt];//printf("sum[rt] = %d  sum[rt<<1] = %d  lazy = %d\n",sum[rt<<1] , sum[rt<<1|1] , lazy[rt]);lazy[rt] = 0;}}void build(int l , int r , int rt){sum[rt] = 0;if(l == r) return ;int m = (l + r)>>1;build(lson);build(rson);}void update(int L , int R , int add , int l , int r , int rt){if(l>=L&&R>=r){sum[rt] = add;lazy[rt] = add;return ;}pushdown(rt);int m = (r+l)>>1;if(m>=L){update(L,R,add,lson);}if(R>m){update(L,R,add,rson);}}/*int query(int L ,int R ,int l ,int r , int rt){if(l>=L&&R>=r){return sum[rt];}pushdown(rt);int m = (l + r)>>1;int ret = 0;if(m>=L){ret = query(L,R,lson);}if(R>m){ret = query(L,R,rson);}return ret;}*/int query(int p, int l,int r ,int rt){if(l == r) return sum[rt];pushdown(rt);int m = (l+r)>>1;if(m>=p) query(p,lson);else query(p,rson);}int main() {int t;int flag = 0 ;char op[2];scanf("%d",&t);while(t--){int a,b;scanf("%d",&n);init();for(int i = 0 ; i < n-1 ; i++){scanf("%d%d",&a,&b);//建边的时候要换一下add(b,a);int da = getf(a);int db = getf(b);//并查集 是为了找到树的根节点在哪里 if(da!=db){p[da] = db;}}int p = getf(1);//根节点dfs(p);//从根节点开始深搜int m;scanf("%d",&m);printf("Case #%d:\n",++flag);for(int i = 0  ; i < m ; i++){scanf("%s",op);if(op[0] == 'C'){scanf("%d",&a);int ans = query(high[a] , 1 , n , 1);printf("%d\n",ans ? ans : -1);}else if(op[0] == 'T'){scanf("%d%d",&a,&b);//printf("a = %d  b = %d\n",a,b);update(high[a] , low[a] , b , 1 , n , 1);}}}}/*154 33 21 35 25 C 3 T 2 1C 3T 3 2C 3*/


原创粉丝点击