hdu5044 Tree 树链拆分,点细分,刚,非递归版本
hdu5044 Tree 树链拆分。点细分。刚,非递归版本
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//#pragma comment(linker, "/STACK:60400000,60400000") //HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s) typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10; const int MAXN = 100020; int n; int e[MAXN][2];
int idx_e[MAXN];
int ans_e[MAXN]; struct Edge{
int to, next;
};
Edge adj[MAXN * 2];
int head[MAXN], tol;
int hd[MAXN]; int top[MAXN];///top[v]表示v所在重链的顶端定点
int fa[MAXN];///fa[v]表示v的父节点,没有为-1
int deep[MAXN];///deep[v]表示v在树中的深度,根点为1
int num[MAXN];///num[v]表示以v为根的子树的节点数 int son[MAXN];///重儿子,没有为-1
int p[MAXN];///p[v]表示v和其父亲节点的连边在线段树的位置(标号) int point_p[MAXN];
int point_pos; int pos; inline void init()
{
tol = 0;///init_edge
//CLR(head, -1);
for (int i = 0; i <= n + 10; i++) head[i] = -1, son[i] = -1; pos = 0;///init_p
//CLR(son, -1); point_pos = 0;
}
inline void add_edge(int u, int v)
{
adj[tol].to = v;
adj[tol].next = head[u];
head[u] = tol++;
} void dfs1(int u, int pre, int d)///求出fa, deep, num, son
{
deep[u] = d;
fa[u] = pre;
num[u] = 1; for (int r = head[u]; r != -1; r = adj[r].next)
{
int v = adj[r].to;
if (v != pre)
{
dfs1(v, u, d + 1);
num[u] += num[v];
if (son[u] == -1 || num[v] > num[son[u]])
son[u] = v;
}
}
} struct sknode{
int u, pre, d;
sknode(){}
sknode(int u, int pre, int d):u(u), pre(pre), d(d)
{
}
};
int fir[MAXN];
void bfs1()
{
stack<sknode>sk;
for (int i = 0; i <= n + 10; i++) hd[i] = head[i], fir[i] = 0; sk.push(sknode(1, -1, 1));
while (!sk.empty())
{
sknode sku = sk.top();
int u = sku.u, d = sku.d, pre = sku.pre;
int r = hd[u];
if (!fir[u])
{
fir[u] = 1;
deep[u] = d;
fa[u] = pre;
num[u] = 1;
}
if (r == -1)
{
if (pre != -1)
{
num[pre] += num[u];
if (son[pre] == -1 || num[u] > num[son[pre]])
son[pre] = u;
}
sk.pop();
}
else
{
int v = adj[r].to;
if (v != pre)
{
sk.push(sknode(v, u, d +1));
}
hd[u] = adj[r].next;
}
}
} void getpos(int u, int sp)///top, p, fp
{
top[u] = sp;
p[u] = ++pos;
ans_e[ idx_e[u] ] = pos;
point_p[u] = ++point_pos; if (son[u] != -1)
getpos(son[u], sp);
else return ;
for (int r = head[u]; r != -1; r = adj[r].next)
{
int v = adj[r].to;
if (v != son[u] && v != fa[u])
getpos(v, v);
}
}
struct node{
int u, sp;
node(){}
node(int u, int sp):u(u), sp(sp){}
};
void bfs2()
{
stack<node> sk;
for (int i = 0; i <= n + 10; i++) hd[i] = head[i], fir[i] = 0;
sk.push(node(1, 1)); while (!sk.empty())
{
node sku = sk.top();
int u = sku.u, sp = sku.sp;
int r = hd[u];
if (!fir[u])
{
fir[u] = 1;
top[u] = sp;
p[u] = ++pos;
ans_e[ idx_e[u] ] = pos;
point_p[u] = ++point_pos; if (son[u] != -1)
{
sk.push(node(son[u], sp));
}
else
{
sk.pop();
}
continue;
}
if (r == -1)
{
sk.pop();
}
else
{
int v = adj[r].to;
if (v != son[u] && v != fa[u])
{
sk.push(node(v, v));
}
hd[u] = adj[r].next;
}
}
} ///
LL sum[2][MAXN];
inline int lowbit(int x)
{
return x & (-x);
}
inline void add(int i, int x, int op)
{
for (; i <= n + 10; i += lowbit(i))
{
sum[op][i] += x;
}
}
inline LL getsum(int i, int op)
{
LL ret = 0;
for (; i > 0; i -= lowbit(i))
ret += sum[op][i];
return ret;
} inline void update(int u, int v, int val, int op)
{
int fu = top[u];
int fv = top[v]; while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(fu, fv);
swap(u, v);
} add(p[fu], val, op);
add(p[u] + 1, -val, op); u = fa[fu]; fu = top[u];
}
if (u == v) return ;
if (deep[u] > deep[v]) swap(u, v); add(p[son[u]], val, op);
add(p[v] + 1, -val, op);
///假设是点剖分的话query(p[u], p[v], 1, pos, 1)
} inline void point_update(int u, int v, int val, int op)
{
int fu = top[u];
int fv = top[v]; while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(fu, fv);
swap(u, v);
} //cout << point_p[fu] << ' ' << point_p[u] <<endl; add(point_p[fu], val, op);
add(point_p[u] + 1, -val, op); u = fa[fu]; fu = top[u];
}
if (deep[u] > deep[v]) swap(u, v);
//cout << point_p[u] << ' ' << point_p[v] <<endl; add(point_p[u], val, op);
add(point_p[v] + 1, -val, op);
///假设是点剖分的话query(p[u], p[v], 1, pos, 1)
} char cc;
inline void read(int &ret)
{
ret = 0;
cc = getchar();
while (cc < '0' || cc > '9') cc = getchar();
while (cc >= '0' && cc <= '9')
{
ret = (ret << 3) + (ret << 1) + cc - '0';
cc = getchar();
}
}
inline void out(LL ret)
{
if (ret > 9) out(ret / 10);
putchar(ret % 10 + '0');
} int main ()
{
char op[10];
int T, Q;
int ncase = 1;
int u, v;
int x, y, z;
read(T);
while (T--)
{
init();
//RII(n, Q);
read(n); read(Q);
FE(i, 1, n - 1)
{
read(e[i][0]); read(e[i][1]);
//RII(e[i][0], e[i][1]);
add_edge(e[i][0], e[i][1]);
add_edge(e[i][1], e[i][0]);
}
bfs1();
//puts("***********");
//dfs1(1, -1, 1);
FE(i, 1, n - 1)
{
if (deep[e[i][0]] > deep[e[i][1]])
swap(e[i][0], e[i][1]);
idx_e[e[i][1]] = i;
}
bfs2();
//puts("***********");
//getpos(1, 1); for (int i = 0; i <= n + 10; i++) sum[0][i] = sum[1][i] = 0;
//CLR(sum, 0);///初始化 while (Q--)
{
scanf("%s", op);
read(x); read(y); read(z);
//scanf("%d%d%d", &x, &y, &z);
if (op[3] == '1')
{
//puts("***********"); point_update(x, y, z, 0);
}
else
{
update(x, y, z, 1);
}
} printf("Case #%d:\n", ncase++);
for (int i = 1; i <= n; i++)
{
out(getsum(point_p[i], 0));
//printf("%I64d", getsum(point_p[i], 0));
//printf("%I64d", getsum(point_p[i], 0));
if (i == n) printf("\n");
else printf(" ");
}
if (n == 1) printf("\n");
else
for (int i = 1; i < n; i++)
{
//printf("%I64d", getsum(mp[make_pair(e[i][1], e[i][0])], 1));
out( getsum(ans_e[i], 1) );
//printf("%I64d", getsum(ans_e[i], 1));
if (i == n - 1) printf("\n");
else printf(" ");
}
}
return 0;
}
版权声明:本文博主原创文章,博客,未经同意不得转载。
hdu5044 Tree 树链拆分,点细分,刚,非递归版本的更多相关文章
- poj 3237 Tree(树链拆分)
题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...
- hdu 4912 Paths on the tree(树链拆分+贪婪)
题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...
- 数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作
AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上 ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- POJ 3237 Tree (树链拆分)
主题链接~~> 做题情绪:了. 解题思路: 主要注意如何区间更新就ok了 . 树链剖分就是树上的线段树. 代码: #include<iostream> #include<sst ...
- poj 3237 Tree 树链剖分
题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
随机推荐
- DiskFileUpload类别
1.2.2 DiskFileUpload类 DiskFileUpload类是Apache文件上传组件的核心类,应用程序开发者通过这个类来与Apache文件上传组件进行交互.以下介绍DiskFileUp ...
- [LeetCode238]Product of Array Except Self
题目: Given an array of n integers where n > 1, nums, return an array output such that output[i] is ...
- 顺序表----java实现
最简单的数据结构--顺序表,此处以数组为例. 顺序表的优点:支持随机读取,内存空间利用率高. 顺序表的缺点:1.需要预先给出最大数据元素个数,这往往很难实现. 2.插入和删除时需要移动大量数据. Se ...
- cocos2d-x box2d Demo注解
勤奋努力,持之以恒. 核心概念 Box2D 中有一些主要的对象,这里我们先做一个简要的定义,在随后的文档里会有更具体的描写叙述. 刚体(rigid body) 一块十分坚硬的物质,它上面的不论什么两点 ...
- 分散式-ubuntu12.04安装spark-1.0.0
1. 安装文档: http://spark.apache.org/docs/latest/spark-standalone.html 2. web UI: master's web UI, which ...
- “MEAN”技术栈开发web应用
“MEAN”技术栈开发web应用 上一篇我们讲了如何使用angular搭建起项目的前端框架,前端抽象出一个service层来向后端发送请求,后端则返回相应的json数据.本篇我们来介绍一下,如何在no ...
- std::list.pop_back() 弹空了列表导致的崩溃
core文件输出: (gdb) bt # # ) at xxxxx/sql/signal_handler.cc: # <signal handler called> # # # # # 0 ...
- 开源 自由 java CMS - FreeCMS2.0 举APP产生信息数据
项目地址:http://www.freeteam.cn/ 生成信息数据 生成当前管理网站下同意移动APP訪问的栏目的信息页面. 从左側管理菜单点击生成信息数据进入. 您能够选择须要生成的栏目,然后点击 ...
- 【足迹C++primer】48、函数引用操作符
函数引用操作符 struct absInt { int operator()(int val) const { cout<<val<<"<->!!!&qu ...
- WP8关于对地图开发的改进
原文:WP8关于对地图开发的改进 微软在2012年6月21日 发布了 Windows Phone 8的更新.带来大量的功能更新和全新的SDK.作为重头戏的部分是引入了 C++ 和 DirectX,支持 ...