HDU3974 - Assign the task(线段树)

来源:互联网 发布:mysql partition by 编辑:程序博客网 时间:2024/05/18 12:01

题目链接 HDU3974

【题意】 给出一棵树,n(<=50000)个结点,m(<=10000)个操作,两种操作:T x y:表示x以及子孙结点的值变为y;

C x:查询x节点当前的值;

【分析】用dfs把树变成序列,第一次访问结点的时候记录下,第二次返回的时候在记录下,按照这个顺序排列成一个序列,比如输入样例,可以表示成序列(2,3,4,4,1,1,3,5,5,2);这样在第一次出现和最后一次出现之间就是所有子孙节点,用线段树存下,这样对于每个T操作就可以直接更新这段,C就是单点查询;

【AC CODE】156ms

#include <cstdio>#include <cstring>#include <cmath>#include <map>//#include <unordered_map>#include <queue>#include <stack>#include <vector>#include <string>#include <algorithm>using namespace std;typedef long long LL;#define rep(i,a,n) for(int i = a; i < n; i++)#define repe(i,a,n) for(int i = a; i <= n; i++)#define per(i,n,a) for(int i = n; i >= a; i--)#define clc(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f#define MAXN 50010#define lc u<<1#define rc u<<1|1struct Edge{int next, v;Edge(int a = 0, int b = 0){next = a, v = b;}}edge[MAXN];struct NODE{int x,y,setv;//setv-lazy标记,在叶子时为值}node[MAXN<<3];int head[MAXN], tol, in[MAXN], st[MAXN], ed[MAXN], cnt;//a[]dfs序列,st[i]员工i在a[]的开始位置,ed为结束位置void add_edge(int u, int v){edge[tol] = Edge(head[u], v);head[u] = tol++;}void dfs(int u)//编号{st[u] = cnt++;for(int i = head[u]; ~i; i = edge[i].next){int v = edge[i].v;dfs(v);}ed[u] = cnt++;}void bulid(int u, int x, int y){node[u].x = x, node[u].y = y;node[u].setv = -1;if(x == y) return;int m = (x+y)>>1;bulid(lc,x,m);bulid(rc,m+1,y);}inline void push_down(int u){if(~node[u].setv){node[lc].setv = node[rc].setv = node[u].setv;node[u].setv = -1;}}int ql,qr,s;//[ql,qr]都修改为svoid update(int u)//区间更新{int x = node[u].x, y = node[u].y;if(ql <= x && y <= qr){node[u].setv = s;return;}push_down(u);int m = (x+y)>>1;if(ql <= m) update(lc);if(qr > m) update(rc);}int p;//p是a[i]中的下标int query(int u)//点值查询{int x = node[u].x, y = node[u].y;if(x == y) return node[u].setv;push_down(u);int m = (x+y)>>1;if(p <= m) return query(lc);return query(rc);}int main(){#ifdef SHYfreopen("e:\\1.txt", "r", stdin);#endifint t, count = 0;scanf("%d%*c", &t);while(t--){int n;scanf("%d%*c", &n);clc(head,-1);clc(in,0);tol = 0;int u,v;rep(i,1,n){scanf("%d %d%*c", &u, &v);add_edge(v,u);in[u]++;}int rt;repe(i,1,n){if(!in[i]){rt = i;break;}}cnt = 1;dfs(rt);bulid(1,1,n<<1);int q;scanf("%d%*c", &q);char str[10];printf("Case #%d:\n", ++count);rep(i,0,q){scanf("%s", &str);if('T' == str[0]){scanf("%d %d%*c", &p, &s);ql = st[p], qr = ed[p];update(1);}else{scanf("%d%*c", &p);p = st[p];printf("%d\n", query(1));}}}return 0;}


 

0 0