ZOJ 3686 A A Simple Tree Problem
来源:互联网 发布:华悦网络加速器怎么样 编辑:程序博客网 时间:2024/06/05 18:24
开始想了一个错误的算法,对每个节点保存它的子树中的节点数目和其中为一的数目,操作某节点时向上更新其祖先的数据(log N),查询时直接输出。当时忽略了操作同时也需要更新后代的数据,这样的最坏复杂度是N,肯定是不行的。但直接交上去不是WA而是超时,由此猜想其中有类似链表的数据。
这个问题可以用线段树很好地解决,在对原树进行先序遍历的同时标上序号后,可以将任意子树转化为区间。序号介于某节点到它的任意后代间的点必为该节点的后代,在这种排序下即可建立线段树,将对子树的操作转化为对区间的操作。
#include <stdio.h>#include <memory.h>#define N 100001#define M 262144#define Negate(x) label[x]=!label[x]#define Comple(a, b) sum[a]=b-sum[a]int right[N];int first[N];int next[N];int num[N];int sum[M];bool label[M];int a, b, ans;int n, m, cnt;void build(int index){int i = first[index];num[index] = ++ cnt;right[index] = cnt;while(i > 0){build(i);if(right[i] > right[index])right[index] = right[i];i = next[i];}}void update(int cur, int l, int r){if(a<=l && b>=r){Negate(cur);Comple(cur, r-l+1);}else{int mid = (l+r) >> 1;int x = cur<<1, y = x+1;if(label[cur] == true){Negate(cur);Negate(x);Negate(y);Comple(x, mid-l+1);Comple(y, r-mid);}if(a <= mid)update(x, l, mid);if(b > mid)update(y, mid+1, r);sum[cur] = sum[x] + sum[y];}}void query(int cur, int l, int r){if (a<=l && b>=r)ans += sum[cur];else{int mid = (l+r) >> 1;int x = cur<<1, y = x+1;if(label[cur] == true){Negate(cur);Negate(x);Negate(y);Comple(x, mid-l+1);Comple(y, r-mid);}if(a <= mid)query(x, l, mid);if(b > mid)query(y, mid+1, r);sum[cur] = sum[x] + sum[y];}}int main(){int node;while(scanf("%d%d", &n, &m) != EOF){memset(first, 0, sizeof(first));for(int i=2; i<=n; ++i){scanf("%d", &node);next[i] = first[node];first[node] = i;}cnt = 0;build(1);memset(label, false, sizeof(label));memset(sum, 0, sizeof(sum));char c[5];for(int j=0; j<m; ++j){scanf("%s", c);scanf("%d", &node);a = num[node];b = right[node];if(c[0] == 'q'){ans = 0;query(1, 1, n);printf("%d\n", ans);}else if(c[0] == 'o')update(1, 1, n);}printf("\n");}return 0;}
- ZOJ 3686 A A Simple Tree Problem
- zoj 3686 A Simple Tree Problem
- ZOJ 3686 : A Simple Tree Problem
- zoj 3686 (a simple tree problem)
- ZOJ 3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem (线段树)
- ZOJ 3686 A Simple Tree Problem (线段树)
- zoj 3686 A Simple Tree Problem(dfs+线段树)
- ZOJ 3686-A Simple Tree Problem (DFS+线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- ZOJ 3686 A Simple Tree Problem DFS+线段树(区间取反)
- zoj 3686 A Simple Tree Problem (经典,利用dfs序维护树)
- ZOJ 3686 A Simple Tree Problem(树转线段树+线段树区间更新)
- ZOJ Monthly, March 2013 A题 A Simple Tree Problem(线段树)#zh
- ZOJ 3686 A Simple Tree Problem(将对树的操作转化成区间=>线段树)
- BNU A Simple Tree Problem 线段树
- ZOJ3696-A Simple Tree Problem 线段树
- TFS版本控制介绍【鸡蛋】
- pg_dump实例详解
- java的B/S模式日志log4j配置及路径
- poj 1742 硬币面值 拼凑 重解 poj 1014
- cakephp2 MeioUpload 图片上传简单应用
- ZOJ 3686 A A Simple Tree Problem
- hdu 1312 Red and Black(搜索)
- 一天一linux命令(11) ln 链接文件
- hibernate isolation 幻读
- jquery.fullCalendar官方文档翻译(一款小巧好用的日程管理日历, 可集成Google Calendar)
- Hibernate 查询多个字段返回的list如何转为自定义对象
- 怎样解题表
- 排序算法小结
- 根据文件编码格式解析html文件