hdu3974(多叉树时间戳建模成线段树)

来源:互联网 发布:网络对战平台 编辑:程序博客网 时间:2024/05/18 17:59
/*translation:一个公司里面每个员工都有一个顶头上司,一旦给某个员工分配任务后,这个员工以及该员工的所有下属都在做该任务。有若干操作,分配给员工任务以及查询该员工正在执行的任务。solution:线段树,时间戳一般化很明显该公司的所有员工间的关系可以用一颗多叉树来表示。然后就是dfs给这棵树打上时间戳。根据新分配的id号码将其节点对应映射到线段树上面。这样分配任务就相当与更新一段连续的节点,查询任务相当与单点查询。note:#: 这道题WA的原因在于搞错了多叉树和线段树间的映射关系。要明白线段树的本质就是对一整段连续区间进行操作。所以这道题的关键就在于清楚怎么将对多叉树的操作转化成对一整段连续区间的操作。date:2016.11.28*/#include <iostream>#include <cstdio>#include <vector>using namespace std;const int maxn = 50000 + 5;vector<int> boss[maxn];vector<int> employee[maxn];int L[maxn*4], R[maxn*4];//节点在树上所对应的覆盖范围以及新分配的idint n, q, cnt;int s[maxn*4], e[maxn*4];int task[maxn*4];void init(){for(int i = 0; i <= n; i++){boss[i].clear();employee[i].clear();}}void dfs(int u){++cnt;L[u] = cnt;for(int i = 0; i < boss[u].size(); i++){int v = boss[u][i];dfs(v);}R[u] = cnt;}void build(int l, int r, int o){s[o] = l;e[o] = r;task[o] = -1;if(l != r){int m = (l + r) >> 1;build(l, m, o << 1);build(m + 1, r, o << 1 | 1);}}void push_down(int o, int num){if(task[o] != -1){task[o << 1] = task[o << 1 | 1] = task[o];task[o] = -1;}}int query(int x, int o){if(s[o] == x && e[o] == x)return task[o];push_down(o, e[o] - s[o] + 1);int m = (s[o] + e[o]) >> 1;if(x <= m)return query(x, o << 1);elsereturn query(x, o << 1 | 1);}void update(int t, int l, int r, int o){if(s[o] == l && e[o] == r){task[o] = t;return;}if(s[o] == e[o])return;push_down(o, e[o] - s[o] + 1);int m = (s[o] + e[o]) >> 1;if(r <= m)update(t, l, r, o << 1);else if(l > m)update(t, l, r, o << 1 | 1);else{update(t, l, m, o << 1);update(t, m + 1, r, o << 1 | 1);}}int main(){//freopen("in.txt", "r", stdin);int T, kase = 0;scanf("%d", &T);while(T--){scanf("%d", &n);init();int u, v;for(int i = 1; i < n; i++){scanf("%d%d", &u, &v);boss[v].push_back(u);employee[u].push_back(v);}cnt = 0;for(int i = 1; i <= n; i++) if(employee[i].size() == 0){dfs(i);break;}build(1, cnt, 1);scanf("%d", &q);printf("Case #%d:\n", ++kase);char op[5];int x, y;while(q--){scanf("%s", op);if(op[0] == 'C'){scanf("%d", &x);printf("%d\n", query(L[x], 1));}else if(op[0] == 'T'){scanf("%d%d", &x, &y);//分配任务y给员工xupdate(y, L[x], R[x], 1);}}}return 0;}

0 0
原创粉丝点击