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. 2014在百度之星程序设计大赛 - 资格 第四个问题 Labyrinth

    小记:dfs暂停,不是决定性的 思维:由于只有三个方向向上和向下和向右,然后,我对待每列从左至右.然后,当在下一列的上一列的处理再加工每个值去获得正确的值,保存各坐标的数组格你可以得到最大值.每处理完 ...

  2. 【Android进阶】使用第三方平台ShareSDK实现新浪微博的一键分享功能

    在公司最近的一个项目中,需要实现一键分享功能,在这里我使用的是第三方平台ShareSDK,将使用经验与大家分享 先看效果图 主界面 分享界面 由于第一次使用,所以需要先进行新浪授权,授权界面 分享结果 ...

  3. sqlserver 无法初始化via支持库[QLVIPL.DLL]

    安装数据库后,在sqlserver configuration manager, sqlserver的网络配置,有将协议 shared memory,named pipes,tcp/ip,via全部启 ...

  4. 写hive sql和shell脚本时遇到几个蛋疼的问题!

    错误一: Hive的where后不能用字段的别名, 错误二: hive的groupby中不能用自己定义函数,否则报错(用嵌套select取代) 错误三: 运行:$ ./hive_game_operat ...

  5. 算法导论学习---红黑树具体解释之插入(C语言实现)

    前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜 ...

  6. java main方法背后的故事?(转)

    jvm java 看似一种语言,实则一个巨大的体系的王国,开发这么多年了,还是没有搞懂,我以为我懂了,可是过了一段时间又忘了,所以说还是没懂 1.main方法说起 编译完我们的java文件后,需要有个 ...

  7. C++学习笔记25,析构函数总是会宣布virtual

    为了永远记住析构函数声明virtual----><<effective c++>> 为这句话不一定对,但无需质疑的是这句话是非常实用的. 查看以下的样例: #includ ...

  8. Android 无法Bind Service

    今天帮同学看一个bindService的样例,说是无法bind service(他接触android时间不长),那代码是从网上找的一个样例,结果看了半天,才终于找到问题所在了),这个问题真是令人挺无语 ...

  9. hdu1381 Crazy Search(hash map)

    题目意思: 给出一个字符串和字串的长度,求出该字符串的全部给定长度的字串的个数(不同样). 题目分析: 此题为简单的字符串哈hash map问题,能够直接调用STL里的map类. map<str ...

  10. NET 中的多线程

    NET 中的多线程 为什么使用多线程 使用户界面能够随时相应用户输入 当某个应用程序在进行大量运算时候,为了保证应用程序能够随时相应客户的输入,这个时候我们往往需要让大量运算和相应用户输入这两个行为在 ...