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 树链拆分,点细分,刚,非递归版本的更多相关文章

  1. poj 3237 Tree(树链拆分)

    题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...

  2. hdu 4912 Paths on the tree(树链拆分+贪婪)

    题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...

  3. 数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作

    AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树.   2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1).   也就是说,AVL树,本质上 ...

  4. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  5. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  6. POJ 3237 Tree (树链拆分)

    主题链接~~> 做题情绪:了. 解题思路: 主要注意如何区间更新就ok了 . 树链剖分就是树上的线段树. 代码: #include<iostream> #include<sst ...

  7. poj 3237 Tree 树链剖分

    题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...

  8. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  9. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

随机推荐

  1. 水声通信(传声)于iOS、Android在情景-depth分析(包括一些声通信源)

    最近的水声通信非常热,特别是,非常嵌入式设备备受瞩目使用,前段时间公布了声通信部分源代码(iOS和Android版本号.下载源的最新版本:点击打开链接 http://download.csdn.net ...

  2. 同一时候使用windows和linux系统

    相信非常多人又想使用方便的windows,可是在开发中必须使用linux,怎样选择呢? 没关系,这里教你怎样制作双系统. 下载wubi,仅仅有几兆大,直接在windows下安装,安装好以后,双系统就制 ...

  3. [Servlet3.0新功能]注释替代配置文件

    作者信息 作者名称:金云龙 个人网站:http://www.longestory.com 个人公众帐号:搜索"longestory"或"龙哥有话说" 须要注意的 ...

  4. 一个不错的 png压缩工具 pngquant 使用介绍 批量压缩png

    1.Png 简介. 我们知道Png 有4个通道,RGBA, 多了一个表示透明的.png 有 png 32, 24, 8 等. 大致我理解的是表示颜色的多少. 数字越小,文件就越小.常见的压缩方式是导入 ...

  5. A*算法进入

    作者文章链接:http://www.policyalmanac.org/games/aStarTutorial.htm 启示式搜索:启示式搜索就是在状态空间中的搜索对每个搜索的位置进行评估,得到最好的 ...

  6. ExtJS4 根据分配不同的树形菜单在不同的角色登录后

    继续我的最后.建立cookie后,带他们出去 var userName = Ext.util.Cookies.get('userName'); var userAuthority = Ext.util ...

  7. 加密解密工具类(Java,DES)

    一个Java版的DES加密工具类,能够用来进行网络传输数据加密,保存password的时候进行加密. import java.security.Key; import java.security.sp ...

  8. 学习json-rpc

    最近做一个和SmartHome相关的项目,文档不全不说,连个像样的Demo都没,痛苦!!当然,这是题外话.今天来说说项目中主要用到的通讯协议:json-rpc,简单地说,它是以json格式进行的远程调 ...

  9. JDK自带的监控分析工具JConsole

    非常多开发人员认为自己懂Java编程.事实是大多数开发人员都仅仅领会到了Java平台的皮毛.所学也仅仅够应付工作. 作者将深度挖掘Java平台的核心功能.揭示一些鲜为人知的事实.帮助您解决最棘手的编程 ...

  10. boostrap-非常好用但是容易让人忽略的地方------input-group-btn

    1.正常的使用 <div class="form-group"> <div class="input-group"> <input ...